为什么 std::sort 不使用我的 operator< 实现
Why doesn't std::sort use my operator< implementation
为什么 std::sort 在 this code
中不使用我的 operator<
实现
#include <iostream>
#include <vector>
#include <tuple>
#include <algorithm>
using namespace std;
bool operator<(
const tuple<int, int>& t1,
const tuple<int, int>& t2
) {
return get<1>(t1) > get<1>(t2);// `>` so that it gets sorted in reverse
}
int main() {
vector<tuple<int, int>> v;
for (int i = 0; i < 10; ++i) {
v.push_back(make_tuple(0, i));
}
cout << "before sort: ";
for (auto& x : v) { cout << get<1>(x) << ", "; }
cout << endl;
auto v2 = v;
sort(v2.begin(), v2.end());
cout << "after sort(begin, end): ";
for (auto& x : v2) { cout << get<1>(x) << ", "; }
cout << endl;
sort(v.begin(), v.end(), [](auto& t1, auto& t2) {
return get<1>(t1) > get<1>(t2);// `>` so that it gets sorted in reverse
});
cout << "after sort(begin, end, comparator): ";
for (auto& x : v) { cout << get<1>(x) << ", "; }
cout << endl;
return 0;
}
输出为:
before sort: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
after sort(begin, end): 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
after sort(begin, end, comparator): 9, 8, 7, 6, 5, 4, 3, 2, 1, 0,
我期望的输出是:
before sort: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
after sort(begin, end): 9, 8, 7, 6, 5, 4, 3, 2, 1, 0,
after sort(begin, end, comparator): 9, 8, 7, 6, 5, 4, 3, 2, 1, 0,
这与名称查找在函数模板中的工作方式有关(通常称为两阶段查找)。 std::sort
在 <algorithm>
中定义,对 <
的查找将在模板定义点(您的不是)的范围内找到这些名称,并在关联的命名空间中找到这些名称依赖函数参数(std::tuple
将是 namespace std
,这也不包括你的)。
由于有问题的参数在命名空间 std
中,将重载添加到该命名空间实际上是未定义的行为。因此,您的选择是要么坚持默认行为(这将是字典顺序 <
),要么提供您自己的自定义比较器(就像您在问题中所做的那样)。
为什么 std::sort 在 this code
中不使用我的operator<
实现
#include <iostream>
#include <vector>
#include <tuple>
#include <algorithm>
using namespace std;
bool operator<(
const tuple<int, int>& t1,
const tuple<int, int>& t2
) {
return get<1>(t1) > get<1>(t2);// `>` so that it gets sorted in reverse
}
int main() {
vector<tuple<int, int>> v;
for (int i = 0; i < 10; ++i) {
v.push_back(make_tuple(0, i));
}
cout << "before sort: ";
for (auto& x : v) { cout << get<1>(x) << ", "; }
cout << endl;
auto v2 = v;
sort(v2.begin(), v2.end());
cout << "after sort(begin, end): ";
for (auto& x : v2) { cout << get<1>(x) << ", "; }
cout << endl;
sort(v.begin(), v.end(), [](auto& t1, auto& t2) {
return get<1>(t1) > get<1>(t2);// `>` so that it gets sorted in reverse
});
cout << "after sort(begin, end, comparator): ";
for (auto& x : v) { cout << get<1>(x) << ", "; }
cout << endl;
return 0;
}
输出为:
before sort: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
after sort(begin, end): 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
after sort(begin, end, comparator): 9, 8, 7, 6, 5, 4, 3, 2, 1, 0,
我期望的输出是:
before sort: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
after sort(begin, end): 9, 8, 7, 6, 5, 4, 3, 2, 1, 0,
after sort(begin, end, comparator): 9, 8, 7, 6, 5, 4, 3, 2, 1, 0,
这与名称查找在函数模板中的工作方式有关(通常称为两阶段查找)。 std::sort
在 <algorithm>
中定义,对 <
的查找将在模板定义点(您的不是)的范围内找到这些名称,并在关联的命名空间中找到这些名称依赖函数参数(std::tuple
将是 namespace std
,这也不包括你的)。
由于有问题的参数在命名空间 std
中,将重载添加到该命名空间实际上是未定义的行为。因此,您的选择是要么坚持默认行为(这将是字典顺序 <
),要么提供您自己的自定义比较器(就像您在问题中所做的那样)。