在调试这个问题时,我遇到了这个。
我将其简化到仅使用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 }
This program compiles and runs fine with C++17 (ubsan/asan enabled) in both GCC and Clang.
When you change the implicit constructor to
explicit
, the problematic lines obviously no longer compile on C++17
令人惊讶的是,两个版本都可以在C++20(v1和v2)上编译,但它们会导致两行代码无限递归(在优化级别上崩溃或紧密循环),而这两行代码在C ++17上无法编译。
显然,通过升级到C++20引入这种潜在错误是令人担忧的。
问题:
- 这是符合C++20的行为吗(我认为是)
- 究竟是什么干扰了?我怀疑可能是由于C++20的新“太空船运算符”支持,但不理解它如何改变此代码的行为。