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

时间:2015-11-04 06:48:37

标签: c++ stl rvalue-reference overloading

{44}在this talk中的Scott Meyers说const在c ++ 0x标准库中使用Rvalue引用来捕获某些不应该是可编译的重载。

用于说明上述要点的代码段会很有帮助。感谢。

1 个答案:

答案 0 :(得分:1)

我发现一个有用的用法是禁用临时成员参与的临时工具。例如,请考虑以下代码:

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构造函数的rvalue,因为rvalues 不会通过构造函数参数绑定到const引用,因此您最终会得到一个悬空引用。为什么const Foo&&而不仅仅是Foo&&?因为如果您使用X(Foo&&) = delete;,那么如果您的get_Foo()返回const Foo(这是一个坏主意,但在实际代码中可以看到),它将绑定到X(const Foo&) ,你最后得到一个悬垂的参考。但是,上面代码中的X(const Foo&&)更适合const Foo rvalue,因此我们获得了无法使用rvalue构建X的预期效果。

您也可以问为什么不为lvalue构造函数定义X(Foo&)。然后你就无法绑定const左值。因此,最好的方法是标记X(const Foo&&) = delete;。希望这能澄清它。