【发布时间】:2018-09-23 13:26:59
【问题描述】:
根据cppreference.com,std::rel_ops::operator!=,>,<=,>= 将在 C++20 中被弃用。
背后的原理是什么?
【问题讨论】:
-
可能是因为C++20采用了三路比较。
标签: c++ standards deprecated c++-standard-library c++20
根据cppreference.com,std::rel_ops::operator!=,>,<=,>= 将在 C++20 中被弃用。
背后的原理是什么?
【问题讨论】:
标签: c++ standards deprecated c++-standard-library c++20
C++20 提供Three way comparison,因此不推荐使用唯一的。
【讨论】:
在 C++20 中,您会得到 three-way comparison(运算符 <=>),如果提供,它会自动“生成”default comparisons:
struct A {
// You only need to implement a single operator.
std::strong_ordering operator<=>(const A&) const;
};
// Compiler generates 4 relational operators (you need to default the
// three-way comparison operator to get == and !=).
A to1, to2;
if (to1 > to2) { /* ... */ } // ok
if (to1 <= to2) { /* ... */ } // ok, single call to <=>
与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,则正确的排序类型。
【讨论】:
<=>。相反,一个人将能够写std::strong_ordering operator<=>(const TotallyOrdered& that) const = default;
背后的原理是什么?
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)【讨论】: