以下程序使用经典的 C++Builder 编译器编译良好,但使用 Clang 编译器编译失败:
#pragma hdrstop
#pragma argsused
#ifdef _WIN32
#include <tchar.h>
#else
typedef char _TCHAR;
#define _tmain main
#endif
#include <stdio.h>
#include <complex>
#include <vector>
#include <algorithm>
typedef std::complex<double> Complex;
bool operator<(const Complex & lhs, const Complex & rhs)
{
return lhs.real() < rhs.real();
}
void doSort()
{
std::vector<Complex> vc;
std::sort(vc.begin(), vc.end());
}
int _tmain(int argc, _TCHAR* argv[])
{
doSort();
return 0;
}
它也可以使用经典编译器进行编译和链接,但如果我添加显式 less 实例,则 Clang 编译器会失败:
std::sort(vc.begin(), vc.end(), std::less<Complex>());
到目前为止,如果我编写一个函数对象,我只能让 Clang 编译器编译:
template <typename T>
struct compLess
{
bool operator()(const T & lhs, const T & rhs) const
{
return lhs < rhs;
}
};
void doSort()
{
std::vector<Complex> vc;
std::sort(vc.begin(), vc.end(), compLess<Complex>());
}
这是根据新的 C++ 标准吗?我还需要做些什么来让 std::less 识别 Complex 的 operator< 吗?
谢谢。
最佳答案
涉及的所有类型和模板 - std::vector
, std::complex
, std::sort
, 和 std::less
- 是 namespace std
的成员. the ADL rules里面什么都没有这将导致在全局命名空间中进行查找,因为不涉及该命名空间。尤其不是因为命名空间 std 包含很多 operator<
(只是这里不需要)。
另一方面,为没有固有顺序的类型(如复数)重载比较并不是一个好主意。它们是二维的,通常不适合线性排序。
你“把戏”(不是真正的戏法)使用显式仿函数作为排序顺序是处理此问题的正确方法。所以就这样做吧。
关于C++Builder Clang std::less 找不到重载的运算符<,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49593048/