请考虑以下代码:
#include <algorithm>
#include <iostream>
#include <vector>
struct A {
int val;
bool operator<(const A& other) const {
std::cout << "operator\n";
return val < other.val;
}
};
void swap(A& a, A& b) {
std::cout << "foo\n";
std::swap(a.val, b.val);
}
int main()
{
std::vector<A> a(2);
a[0].val = 10;
a[1].val = -1;
std::sort(a.begin(), a.end());
}
Run Code Online (Sandbox Code Playgroud)
C++ 11的std::sort地方ValueSwappable的迭代器参数的要求,移动语义,没有别的,这意味着std::sort是"保证",如果内容需要四处走动,进行互换.并且17.6.3.2/3暗示在这种情况下我的过载肯定应该被选中.
clang 3.1 SVN的libc ++选择我swap(也就是说,我看到"foo"); GCC 4.6.3的libstdc ++没有.
C++ 11的
std::sort地方ValueSwappable的迭代器参数的要求,移动语义,没有别的,这意味着std::sort是"保证",如果内容需要四处走动,进行互换.
我没有看到这种保证.谁说std::sort不能使用移动语义而不是交换?事实上,在浏览了逐字规范的标准之后,我相信这正是发生的事情:
要求:
RandomAccessIterator应满足ValueSwappable(17.6.3.2)的要求.其类型*first应满足MoveConstructible(表20)和MoveAssignable(表22)的要求.
请注意,迭代器应该是ValueSwappable,而不是它们指向的元素.
我发布这个作为答案,因为我没有评论的声誉.
正如@FredOverflow指出的那样,libstdc ++在排序时使用移动构造函数和赋值运算符.但是,我发现奇怪的是它没有将ADL用于pre c ++ 11代码,因此人们可以插入优化的交换功能.