Const Rvalue引用捕获不应该可编译的重载
Const Rvalue reference to capture overloads which are not supposed to be compilable
Scott Meyers在44:15的演讲中表示,const
Rvalue引用在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()
返回const Foo
(这是一个坏主意,但在实际代码中可以看到),它将绑定到X(const Foo&)
,并且您最终会得到一个悬空引用。然而,上面代码中的X(const Foo&&)
与const Foo
右值更好地匹配,因此我们获得了无法构造具有右值的X
的期望效果。
您可能还会问,为什么不为左值构造函数定义X(Foo&)
。那么您将无法绑定const
lvalues。因此,最好的方法是标记X(const Foo&&) = delete;
。希望这能澄清这一点。
相关文章:
- 在缺少函数重载时抛出异常,并带有 std::variant 而不是编译时错误
- 错误:使用 clang 没有可行的重载,使用 GCC 编译
- 使用 MINGW gcc 编译时,不会为 std::string 调用重载的新运算符
- 编译以下重载<<需要什么enable_if或其他提示?
- C++编译时检查是否可以用某种类型的参数调用重载函数
- ostream 运算符的编译时重载
- 如何在C++编译时检查运算符的特定重载是否存在
- 简单的 SFINAE 示例以重载函数不编译
- 当其中一个函数未编译时,函数重载查找如何工作?
- 重载运算符编译错误?
- C++ - 在 std::thread 中调用重载函数时编译失败
- 如何重载 const 对象的 [],以便值赋值不会导致编译错误
- 使用 C++11 选项编译 C++98 代码时由于 Boost 标头而导致的不明确重载
- 编译错误:2 个重载没有'this'指针的合法转换。使用结构
- 线性重载:为什么 clang 在 GCC 编译时失败?
- C++运算符新重载、编译错误
- 在编译时推导具有未知类型的函数重载
- 使用 std::enable_if 的模板重载的隐式转换运算符 T() 无法编译
- 重载运算符时出现编译错误
- 运算符未编译'+'重载