考虑:
#include <algorithm>
#include <vector>
struct A {
double dummy;
bool operator<(const A& a) { ///Here I am missing a `const`
return dummy < a.dummy;
}
};
int main()
{
std::vector<A> a;
a.push_back({0.9});
a.push_back({0.4});
std::sort(a.begin(),a.end());
return 0;
}
这在 gcc 上编译得很好,但在 clang 上它给出了/usr/include/c++/v1/algorithm:719:71: error: invalid operands to binary expression ('const A' and 'const A')
bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;}
以及一长串失败的实例化。这是我的最小示例:https://rextester.com/VEO17629
当我找到 Invalid operand to binary expression on std::max_element 时,我终于可以解决它了(
operator <
必须有一个 const
说明符)。奇怪的是,如果我调用
std::sort
,错误也会消失。指定运算符 std::less<>()
:std::sort(a.begin(),a.end(),std::less<>());
为什么要指定比较运算符 std::less<>()
解决错误?
最佳答案
Why does specifying the compare operator
std::less<>()
solve the error?
有趣的是,只有当您使用
std::less<void>
( std::less<>
) 它编译。 std::less<A>
才不是。std::less<A>::operator()
:constexpr bool operator()( const T& lhs, const T& rhs ) const;
std::less<void>::operator()
签名略有不同,未指定 const T&
:template< class T, class U>
constexpr auto operator()( T&& lhs, U&& rhs ) const
-> decltype(std::forward<T>(lhs) < std::forward<U>(rhs));
所以,std::less<void>::operator()
可免费调用非const
operator<
.g++
之间的区别( libstdc++
) 和 clang++
( libc++
) 可以有一些不同的解释。一种是如果 libstdc++
转发 std::sort(a.begin(),a.end())
至std::sort(a.begin(),a.end(), std::less<>{})
而不是使用 operator<
直接地。在 C++14 中(您在演示中使用)
[alg.sorting]/1
只是说:“25.4 中的所有操作都有两个版本:一个采用 Compare
类型的函数对象,另一个使用 operator<
。”。没有什么禁止使用
std::less<void>
调用operator<
.在 C++20 中
[sort]/1
甚至还有一个补充,在没有给出比较器时准确指定该行为:“ 让
comp
为 less{}
和 proj
为 identity{}
用于这些名称没有参数的重载。”。 clang++
/libc++
但是,在 C++20 模式下无法遵守这一点。
关于c++ - std::sort 中二进制表达式错误(缺少 const)的无效操作数:为什么指定比较运算符可以解决它?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67019075/