应该使用我的`swap`重载吗?这是一个libstdc ++(GCC)错误吗?

Lig*_*ica 2 c++ gcc std clang

请考虑以下代码:

#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 ++没有.

  • 这是一个GCC错误(假设我的标准解释是正确的)?或者我错过了什么?

fre*_*low 6

C++ 11的std::sort地方ValueSwappable的迭代器参数的要求,移动语义,没有别的,这意味着std::sort是"保证",如果内容需要四处走动,进行互换.

我没有看到这种保证.谁说std::sort不能使用移动语义而不是交换?事实上,在浏览了逐字规范的标准之后,我相信这正是发生的事情:

要求:RandomAccessIterator应满足ValueSwappable(17.6.3.2)的要求.其类型*first应满足MoveConstructible(表20)和MoveAssignable(表22)的要求.

请注意,迭代器应该是ValueSwappable,而不是它们指向的元素.


Ped*_*dro 6

我发布这个作为答案,因为我没有评论的声誉.

正如@FredOverflow指出的那样,libstdc ++在排序时使用移动构造函数和赋值运算符.但是,我发现奇怪的是它没有将ADL用于pre c ++ 11代码,因此人们可以插入优化的交换功能.

  • 得到一些代表并开始评论:) (2认同)