Почему void B::f() const & выбирается, когда B:: f вызывается временным объектом B?

#include <iostream>

struct A
{
    void f() const &
    {
        std::cout << "A::f()&" << std::endl;
    }

    void f() const &&
    {
        std::cout << "A::f()&&" << std::endl;
    }
};

struct B
{
    void f() const &
    {
        std::cout << "B::f()&" << std::endl;
    }
};

int main()
{
    A{}.f();
    B{}.f();
}

Выход:

A:: F ()&&

B:: F ()&

Обратите внимание, что void B::f() const && не существует

Для меня временный объект B звонки B::f, void B::f() const && должен быть выбран, или ошибка компилятора должна возникнуть.

Почему void B::f() const & выбрал в таком случае?

1 ответ

Решение

Так как void B::f() const && не существует, выбран следующий лучший кандидат, который является вашим void B::f() const &, Значение будет привязано к const &, Если вы удалите const, вы заметите, что получите ошибку компиляции, поскольку rvalue не может привязаться к неконстантной ссылке. Пример https://en.cppreference.com/w/cpp/language/overload_resolution прекрасно это показывает.

int i;
int f1();
int g(const int&);  // overload #1
int g(const int&&); // overload #2
int j = g(i);    // lvalue int -> const int& is the only valid conversion
int k = g(f1()); // rvalue int -> const int&& better than rvalue int -> const int&

Это не отличается для неявного this аргумент в ваших примерах.

Для меня временный объект из B вызывает B::f, void B::f() const && должен быть выбран, или должна возникнуть ошибка компилятора.

если бы это было так, то код, подобный следующему, сломался бы без существующей перегрузки [const] rvalue.

void f(const int& i)
{
    std::cout << i;
}

int main()
{
    f(3);
}
Другие вопросы по тегам