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;
。希望这可以澄清。
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;
。希望这可以澄清。