我在调试这个问题时遇到了这个问题。
我一直将其修剪为仅使用Boost Operators:
-
#include <boost/operators.hpp> struct F : boost::totally_ordered1<F, boost::totally_ordered2<F, int>> { /*implicit*/ F(int t_) : t(t_) {} bool operator==(F const& o) const { return t == o.t; } bool operator< (F const& o) const { return t < o.t; } private: int t; }; int main() { #pragma GCC diagnostic ignored "-Wunused" F { 42 } == F{ 42 }; // OKAY 42 == F{42}; // C++17 OK, C++20 infinite recursion F { 42 } == 42; // C++17 OK, C++20 infinite recursion }
该程序可以在 GCC 和 Clang 中使用 C++17(启用 ubsan/asan)编译和运行良好。
当您将隐式构造函数更改为 时
explicit
,有问题的行显然不再在 C++17 上编译
令人惊讶的是,这两个版本都在 C++20 (v1和v2)上编译,但它们导致在 C++17 上无法编译的两行上的无限递归(崩溃或紧密循环,取决于优化级别)。
显然,这种通过升级到 C++20 潜入的无声 bug 令人担忧。
问题:
- 这是否符合 c++20 行为(我希望如此)
- 究竟是什么干扰?我怀疑这可能是由于 c++20 的新“宇宙飞船操作员”支持,但不明白它如何改变这段代码的行为。