Const Rvalue 引用以捕获不应编译的重载

Const Rvalue reference to capture overloads which are not supposed to be compilable

Scott Meyers 在 this talk at 44:15 中说 const 右值引用在 c++0x 标准库中用于捕获某些不应编译的重载。

说明上述要点的代码片段会有所帮助。谢谢

我发现有用的一种用法是禁止临时投标引用成员。例如,考虑下面的代码:

struct Foo{};

class X
{
    const Foo& _foo;
public:    
    X(const Foo&&) = delete;       // prevents rvalue binding
    X(const Foo& foo): _foo(foo){} // lvalue is OK
};

Foo get_Foo()
{
    return {};
}

const Foo get_const_Foo()
{
    return {};
}

Foo& get_lvalue_Foo()
{
    static Foo foo;
    return foo;
}

int main() 
{
//  X x1{get_Foo()};        // does not compile, use of deleted function
//  X x2{get_const_Foo()};  // does not compile, use of deleted function
    X x3{get_lvalue_Foo()}; // OK
}

您肯定想禁止将右值传递给 X 的构造函数,因为右值 不会通过构造函数参数绑定到 const 引用 ,所以您最终有一个悬垂的参考。为什么是 const Foo&& 而不是 Foo&&?因为如果你使用 X(Foo&&) = delete;,那么如果你的 get_Foo() returns const Foo (这是一个坏主意,但在实际代码中仍然可以看到),它将绑定到 X(const Foo&) 相反,你最终会得到一个悬垂的引用。但是,上面代码中的 X(const Foo&&) 更适合 const Foo 右值,因此我们获得了无法构造带有右值的 X 的预期效果。

您可能还会问为什么不为左值构造函数定义 X(Foo&)。那么你将无法绑定 const 左值。所以最好的做法是标记X(const Foo&&) = delete;。希望这可以澄清。