为什么在C++ 20中不推荐使用std :: rel_ops :: operators?

xml*_*lmx 18 c++ standards deprecated c++-standard-library c++20

根据cppreference.com,std::rel_ops::operator!=,>,<=,>=将在C++ 20中弃用.

背后的理由是什么?

Hol*_*olt 24

在C++ 20中,您将获得三向比较(运算符<=>),如果提供,它将自动"生成" 默认比较:

struct A {
   // You only need to implement a single operator.
   std::strong_ordering operator<=>(const A&) const;
};

// Compiler generates all 6 relational operators
A to1, to2;
if (to1 == to2) { /* ... */ } // ok
if (to1 <= to2) { /* ... */ } // ok, single call to <=>
Run Code Online (Sandbox Code Playgroud)

三向比较有多个优点std::rel_ops,这可能是std::rel_ops运营商被弃用的原因.在我的头顶:

  • 这是因为更灵活,根据不同的返回类型operator<=>(std::strong_ordering,std::weak_ordering,...),仅生成相关的运营商.有关<compare>更多信息,请参阅标题.

  • 这样做不会带来一堆模板化的运算符重载using namespace std::rel_ops.

  • 你可以要求编译器通过默认生成三通运算符(auto operator<=>(A const&) = default) - 这基本上会生成基类和非静态数据成员的字典比较,如果返回类型,它将推导出正确的排序类型是auto.

  • 无法帮助自己,但"宇宙飞船运营商"听起来比"三方比较"更酷:P (8认同)

Bar*_*rry 9

背后的理由是什么?

rel_ops太空船(比较)运营商图书馆支持已弃用.该论文没有列出任何动机,但确实出现在宇宙飞船论文中:

这包含了名称空间std::rel_ops,因此我们建议删除(或弃用)std::rel_ops.

本文提到了四个原因(包括正确性和性能).但是在两篇论文中都没有提到的一个大问题是std::rel_ops......只是......不起作用.经验法则是使用ADL找到运算符.rel_ops不会给你ADL可查找的运算符,它只是声明无约束的函数模板,如:

namespace std {
    namespace rel_ops {
        template< class T >
        bool operator!=( const T& lhs, const T& rhs ) 
        {
            return !(lhs == rhs);
        }
    }    
}
Run Code Online (Sandbox Code Playgroud)

所以使用如下算法:

struct X { ... };
bool operator<(X const&, X const&) { ... };
std::sort(values.begin(), values.end(), std::greater<>{});
Run Code Online (Sandbox Code Playgroud)

只是不起作用,除非你确保:

#include <utility>
using namespace std::rel_ops;
Run Code Online (Sandbox Code Playgroud)

在您的第一个包括确保这些操作符在您可能调用的每个功能模板的定义点上都可见时,每个地方都相当一致.

所以operator<=>只是严格优越:

  • 它确实有效.
  • 你只需编写一个函数(<=>)而不是两个(==<)
  • 通常,您实际上必须写零函数(= default)
  • 我提到它确实有效吗?