【问题标题】:const& , & and && specifiers for member functions in C++C++ 中成员函数的 const& 、 & 和 && 说明符
【发布时间】:2015-03-19 22:42:51
【问题描述】:

最近我在阅读API of boost::optional 并遇到了以下问题:

T const& operator *() const& ;
T&       operator *() & ;
T&&      operator *() && ;

我还编写了自己的程序,将成员函数定义为 const&、& 和 &&(请注意,我不是在谈论返回类型,而是在分号之前的说明符),它们似乎工作正常。

我知道声明一个成员函数 const 意味着什么,但谁能解释一下声明它是什么意思 const&、& 和 &&。

【问题讨论】:

    标签: c++ c++11 constants


    【解决方案1】:

    const& 表示,此重载将仅用于 const、非 const 和左值对象。

    const A a = A();
    *a;
    

    & 表示,此重载将仅用于非常量对象。

    A a;
    *a;
    

    && 表示,此重载将仅用于右值对象。

    *A();
    

    有关 C++11 标准这一特性的更多信息,您可以阅读这篇文章What is "rvalue reference for *this"?

    【讨论】:

    • 如果有帮助,我喜欢将这些限定符视为应用于“秘密”作为方法的第一个参数传入的 *this 对象。
    • const&& 表示它们将用于const 和非const lvalue&& 将仅用于右值,不一定是引用。
    • 实际上,const & 可以绑定到几乎任何东西,甚至是右值。适用于任何参数绑定的类似规则 - const T& 有点特殊 - 它可以绑定到任何不是 volatile IIRC
    • @john_zac 你是对的,他们为什么这样做,不,编译器不能在它认为合适的时候引入std::moves。它可能会破坏类的不变量、RAII 语义等。标准中唯一允许类似的地方是return,首先尝试作为右值返回。
    • @john_zac,正如你所问,这些并不是“必要的”。但是它们提供了某些可选的优化。您可以只使用T operator *(); 就可以逃脱 - 这会编译但它会产生一些奇怪的后果 - *p = x 不会做你期望它做的事情。我认为重要的是返回类型——我们想要多个具有不同返回类型的重载。一旦您了解了不同返回类型的可取性,那么您还会看到我们需要最后的限定符来控制每次调用使用哪个重载(以及因此哪个返回类型)。
    【解决方案2】:

    它是成员函数 ref-qualifiers,它是 C++11 中添加的特性之一。通过指定函数引用限定符 (some details),可以根据隐式 this 对象参数是左值还是右值来重载非静态成员函数。

    要为非静态成员函数指定引用限定符,您可以使用&&& 限定函数。

    #include <iostream>
    struct myStruct {
        void func() & { std::cout << "lvalue\n"; }
        void func() &&{ std::cout << "rvalue\n"; }
    };
    
    int main(){
        myStruct s;
        s.func();            // prints "lvalue"
        std::move(s).func(); // prints "rvalue"
        myStruct().func();   // prints "rvalue"
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-12-14
      • 1970-01-01
      • 2020-03-24
      • 1970-01-01
      • 2023-03-14
      • 1970-01-01
      相关资源
      最近更新 更多