右值引用是否满足Cpp17MoveConstructible要求?
右值引用是否满足Cpp17MoveConstructible要求?
要满足该要求,表达式T u = rv;中u需与rv“等价”。若T为右值引用(如int&&),则int&& u = 0;中u需与0等价,但引用是否能与值等价,还是仅指向等价的对象?
动机
提出该问题是因为std::swap<int&&>的预期行为不明确。is_move_constructible_v<int&&>和is_move_assignable_v<int&&>的值为true,满足std::swap的约束可实例化,但如果int&&不满足Cpp17MoveConstructible,swap<int&&>的行为将未定义。
事实上,所有主流实现(libc++、libstdc++、MSVC STL)的std::swap(a, b)大致如下:
T t = std::move(a); a = std::move(b); b = std::move(t);
若T为右值引用,T t = std::move(a)并非创建移动构造的副本,而是将右值引用绑定到另一个右值引用。对于T = int&&,其效果等价于:
a = a; b = a;
对此有两种观点:
- 右值引用不满足Cpp17MoveConstructible,所有实现均正确,因
swap的前置条件未满足,行为可如此。 - 右值引用满足Cpp17MoveConstructible,所有实现均错误。
究竟哪种正确?
注:议题LWG4047“不应支持显式指定std::swap的模板参数”解决了部分相关问题。
内容的提问来源于stack exchange,提问作者Jan Schultke
相关产品推荐
相关产品推荐

