我的“交换”过载应该被使用吗?这是一个libstdc++(GCC)错误吗
Is my `swap` overload supposed to be used? Is this a libstdc++ (GCC) bug?
考虑以下代码:
#include <algorithm>
#include <iostream>
#include <vector>
struct A {
int val;
bool operator<(const A& other) const {
std::cout << "operatorn";
return val < other.val;
}
};
void swap(A& a, A& b) {
std::cout << "foon";
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());
}
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错误吗(假设我的标准解释是正确的)?还是我错过了什么
C++11的
std::sort
在迭代器参数、移动语义和其他方面都提出了ValueSwappable要求,这意味着如果元素需要四处移动,std::sort
"保证"执行交换。
我看不出有什么保证。谁说std::sort
不能使用移动语义而不是交换?事实上,在浏览了逐字逐句规范的标准后,我相信这正是发生的事情:
要求:
RandomAccessIterator
应满足ValueSwappable
(17.6.3.2)的要求。*first
的类型应满足MoveConstructible
(表20)和MoveAssignable
(表22)的要求
请注意,迭代器应为ValueSwappable
,而不是它们所指向的元素。
我把这作为一个答案发布,因为我没有声誉可以评论。
正如@FredOverflow所指出的,libstdc++在排序时使用移动构造函数和赋值运算符。然而,我觉得奇怪的是,它没有将ADL用于c++11之前的代码,这样人们就可以插入优化的交换函数。
相关文章:
- 如果静态变量只为程序的整个部分存储了一个副本,为什么我不能使用静态变量交换 2 个数字?
- 使用 STL 交换堆栈 C++ 中的第一个和最后一个元素
- 给定一个无符号整数,很容易交换每个偶数位和奇数位。这可以推广到交换每个偶数和奇数n位吗?
- 简单链表与下一个>下一个交换
- 编写一个功能,该函数将使用框架交换两个整数
- 如何在这个交换函数(一个单独的链表)中找到错误
- 交换C 中的第一个和最后一个节点
- std::atomic<int*>::load 应该做一个比较和交换循环吗?
- 如何在C++中交换队列的第一个和最后一个元素
- 将一个元素与矢量中的所有其他元素交换
- 如何测试我的FIX客户端?有没有一个假的FIX交换,我可以使用
- 将类成员向量的内容复制到另一个向量中,然后将其交换回
- select() 在一个简单的自制 p2p 程序中与 udp 交换"musicdata"的问题
- 使用一个函数在两个不同的类中交换指针
- 是否有一个快速的内存中队列,我可以使用它在达到一定大小时交换项目
- 在交换链中为每个渲染目标创建一个分配器是否有意义
- 我应该清除作为参数传入的()容器,还是交换一个新对象
- 将具有指针的向量元素从一个派生类交换到另一派生类
- 我正在编写一个排序函数,以升序对字符类型列表进行排序,如果有任何交换,则返回计数次数
- 我的“交换”过载应该被使用吗?这是一个libstdc++(GCC)错误吗