为什么在B的临时对象调用B :: f时选择void B :: f()const&选择?

时间:2018-10-26 01:20:07

标签: c++ c++11 overloading rvalue-reference ref-qualifier

#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::fvoid B::f() const &&的临时对象,否则会引起编译器错误。

在这种情况下为什么选择void B::f() const &

1 个答案:

答案 0 :(得分:4)

由于void B::f() const &&不存在,因此选择了下一个最佳候选者是您的void B::f() const &。右值将绑定到const &。如果删除const,您会注意到会出现编译错误,因为rvalue无法绑定到非const引用。 cppreference/overloadresolution上的示例完美地展示了它。

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]右值引用重载的情况下,类似following的代码就会中断。

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

int main()
{
    f(3);
}