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

时间:2018-04-13 08:38:43

标签: c++ standards deprecated c++-standard-library c++20

根据cppreference.com,{+ 1}}将在C ++ 20中弃用。

背后的理由是什么?

3 个答案:

答案 0 :(得分:22)

在C ++ 20中,您得到three-way comparison(运算符<=>),它会自动生成&#34;生成&#34; default comparisons如果提供:

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 <=>

std::rel_ops相比,三向比较有多个优势,这可能是为什么std::rel_ops运算符被弃用的原因。在我的头顶:

  • 它更具通用性,因为根据operator<=>std::strong_orderingstd::weak_ordering,...)的返回类型,只会生成相关的运算符。有关详细信息,请参阅<compare>标题。

  • 通过执行using namespace std::rel_ops,您不会带来一堆模板化的运算符重载。

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

答案 1 :(得分:8)

  

背后的理由是什么?

rel_ops已被Library Support for the Spaceship (Comparison) Operator弃用。该论文没有列出任何动机,但确实出现在spaceship paper

  

这包含了名称空间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);
        }
    }    
}

因此使用以下算法:

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

除非你确定:

,否则不起作用
#include <utility>
using namespace std::rel_ops;

无处不在,因为您的第一个包括确保这些运算符在您可能调用的每个函数模板的定义点都可见。

所以operator<=>只是非常优越:

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

答案 2 :(得分:2)

C ++ 20提供Three way comparison,因此唯一的那些将被弃用。