c++ - std::sort 中二进制表达式错误(缺少 const)的无效操作数:为什么指定比较运算符可以解决它?

原文 标签 c++ sorting gcc clang operator-overloading

考虑:

#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 甚至还有一个补充,在没有给出比较器时准确指定该行为:
compless{} projidentity{} 用于这些名称没有参数的重载。”。 clang++/libc++但是,在 C++20 模式下无法遵守这一点。

关于c++ - std::sort 中二进制表达式错误(缺少 const)的无效操作数:为什么指定比较运算符可以解决它?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67019075/

相关文章:

c - malloc : error double free with printf and a NULL wchar_t*

c++ - C++ 中的释放(指针 vector 数组)

C++ 实现具有多级继承的对象相等性

android - 存储任意排序顺序的最有效方法?

c - 为什么 gcc 支持 std=gnu89 的 bool 类型?

c - 如何减少 C 中深度递归函数的堆栈帧?

c++ - C++ stoi:2个重载都不能转换所有参数类型

c++ - C++将字节转换为操作码?

python - 两种不同标准的连续排序

mysql - SQL ORDER字符串(NumberOrder/年)