考虑:
#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/