【问题标题】:Why is void B::f() const & chosen when B::f is called by a temporary object of B?当 B::f 被 B 的临时对象调用时,为什么选择 void B::f() const &?
【发布时间】:2018-10-26 01:20:06
【问题描述】:
#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 &amp;&amp; 不存在。

对我来说,应该选择B 调用B::fvoid B::f() const &amp;&amp; 的临时对象,否则应该引发编译器错误。

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

【问题讨论】:

  • 我认为这只是因为您根本没有void f() const &amp;&amp;,C++ 似乎倾向于允许您编写更灵活的代码,而不是限制您手动进行微优化。这类似于在没有移动构造函数的情况下使用Object(const Object &amp;) 调用std::move(object)

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


【解决方案1】:

因为void B::f() const &amp;&amp; 不存在,所以选择下一个最佳候选人,即您的void B::f() const &amp;。右值将绑定到const &amp;。如果您删除 const,您会注意到您将收到编译错误,因为右值无法绑定到非 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 &&,否则应该引发编译器错误。

如果是这种情况,那么像 following 这样的代码会在不存在 [const] 右值引用重载的情况下中断。

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

int main()
{
    f(3);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-13
    • 1970-01-01
    • 2020-02-04
    • 1970-01-01
    相关资源
    最近更新 更多