最佳答案
我在调试 这个问题时遇到了这个问题。
我把它简化到只用 Boost Operators:
编译器资源管理器 C + + 17 < a href = “ https://Godbolt.org/z/szYx9E”rel = “ noReferrer”> C + + 20
#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
时,问题行显然 < strong > < a href = “ https://Godbolt.org/z/hq4fve”rel = “ noReferrer”> 不再在 C + + 17上编译
令人惊讶的是,这两个版本的 在 C + + 20上编译(ref = “ https://Godbolt.org/z/onMzo5”rel = “ noReferrer”> v1 和 < a href = “ https://Godbolt.org/z/b1Pav5”rel = “ noReferrer”> v2 ),但他们导致 无限递归(崩溃或紧密循环,取决于优化水平)的两行,不会在 C + + 17上编译。
很明显,这种通过升级到 C + + 20而悄然出现的无声 bug 令人担忧。
问题: