[英]Invalid operands to binary expression error (missing const) in std::sort: Why does specifying the compare operator solve it?
Considering:考虑:
#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;
}
This compiles fine on gcc, but on clang it gives这在 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;}
and a long list of failed instantiation.以及一长串失败的实例化。 Here is my minimal example in action: https://rextester.com/VEO17629
这是我的最小示例: https://rextester.com/VEO17629
I could finally solve it when I found Invalid operand to binary expression on std::max_element (the operator <
must have a const
specifier).当我在 std::max_element 上发现二进制表达式的无效操作数时,我终于可以解决它(
operator <
必须有一个const
说明符)。
The curious thing is that the error goes away also if I call std::sort
specifying the operator std::less<>()
:奇怪的是,如果我调用
std::sort
指定运算符std::less<>()
,错误也会消失:
std::sort(a.begin(),a.end(),std::less<>());
Why does specifying the compare operator std::less<>()
solve the error?为什么指定比较运算符
std::less<>()
可以解决错误?
Why does specifying the compare operator
std::less<>()
solve the error?为什么指定比较运算符
std::less<>()
可以解决错误?
Interestingly enough, it's only when you use std::less<void>
( std::less<>
) that it compiles.有趣的是,只有当您使用
std::less<void>
( std::less<>
) 时它才会编译。 std::less<A>
does not. std::less<A>
没有。
std::less<A>::operator()
: std::less<A>::operator()
:
constexpr bool operator()( const T& lhs, const T& rhs ) const;
The std::less<void>::operator()
has a slightly different signature, not specifying const T&
: 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));
So, the std::less<void>::operator()
is free to call the non- const
operator<
.因此,
std::less<void>::operator()
const
自由调用非常量operator<
。
The difference between g++
( libstdc++
) and clang++
( libc++
) can have some different explanations. g++
( libstdc++
) 和clang++
( libc++
) 之间的区别可以有一些不同的解释。 One would be if libstdc++
forwards std::sort(a.begin(),a.end())
to std::sort(a.begin(),a.end(), std::less<>{})
instead of using operator<
directly.一种是如果
libstdc++
将std::sort(a.begin(),a.end())
转发到std::sort(a.begin(),a.end(), std::less<>{})
而不是直接使用operator<
。
In C++14 (that you used in your demo) [alg.sorting]/1
just says: " All the operations in 25.4 have two versions: one that takes a function object of type Compare
and one that uses an operator<
. ".在 C++14(您在演示中使用的)
[alg.sorting]/1
中只是说:“ 25.4 中的所有操作都有两个版本:一个采用 function ZA8CFDE6331BD59EB2AC96F891 类型的operator<
。 Compare
There is nothing prohibiting using std::less<void>
to call operator<
.没有什么禁止使用
std::less<void>
调用operator<
。
In C++20 [sort]/1
there has even been an addition, specifying exactly that behavior when no comparator is given: " Let comp
be less{}
and proj
be identity{}
for the overloads with no parameters by those names. ".在 C++20
[sort]/1
中甚至还添加了一个,在没有给出比较器时准确指定该行为:“对于没有这些名称的参数的重载,让comp
为less{}
和proj
为identity{}
。 ”。 clang++
/ libc++
in C++20 mode fails to comply to this though.但是,C++20 模式下的
clang++
/ libc++
未能遵守这一点。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.