这是一个可能的定义std::swap
:
template<class T>
void swap(T& a, T& b) {
T tmp(std::move(a));
a = std::move(b);
b = std::move(tmp);
}
我相信
std::swap(v,v)
保证没有任何影响,并且std::swap
可以如上实现。
在我看来,以下引用似乎暗示这些信念是矛盾的。
17.6.4.9 函数参数 [res.on.arguments]
1 除非另有明确说明,否则以下各项均适用于 C++ 标准库中定义的函数的所有参数。
...
- 如果函数参数绑定到右值引用参数,则实现可能假定此参数是对该参数的唯一引用。[ 注意:如果参数是 T&& 形式的泛型参数并且绑定了类型 A 的左值,则参数绑定到左值引用 (14.8.2.1),因此上一句未涵盖。— end note ] [ 注意:如果程序将左值转换为 xvalue,同时将该左值传递给库函数(例如,通过使用参数 move(x) 调用函数),则程序实际上是在要求该函数处理该左值作为临时。如果参数是左值,则该实现可以免费优化别名检查,这可能需要。——尾注]
(感谢Howard Hinnant提供报价)
让v
成为从标准模板库中获取的某种可移动类型的对象并考虑调用std::swap(v, v)
。在上面的行中, thata = std::move(b);
内部就是这种情况,因此参数不是唯一的引用。这违反了上述要求,因此该行在调用时调用未定义的行为 from 。T::operator=(T&& t)
this == &b
a = std::move(b)
std::swap(v, v)
这里的解释是什么?