std::sort 中的二进制表达式错误(缺少常量)的无效操作数:为什么指定比较运算符可以解决它?
Invalid operands to binary expression error (missing const) in std::sort: Why does specifying the compare operator solve it?
正在考虑:
#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
当我找到(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 模式下不符合这一点。
正在考虑:
#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
当我找到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 模式下不符合这一点。