rollbear / dry-comparisons

C++17 Utility classes for comparing multiple values in one simple expression
The Unlicense
204 stars 13 forks source link

Disable new comparison rules to avoid infinite loop. #6

Closed nebularnoise closed 3 years ago

nebularnoise commented 3 years ago

Makes the lib build in GCC 10.2 with std=c++20

Before adding this change, this was the compiler error:

dry-comparisons.hpp:106:27: fatal error: template instantiation depth exceeds maximum of 900 (use '-ftemplate-depth=' to increase the maximum)
  106 |     template <typename U, typename = std::enable_if_t<!std::is_same<U, any_of>{}>>
rollbear commented 3 years ago

Thank you. I see. I need to set up a proper CI matrix for many compilers, to ensure a change for one compiler doesn't accidentally break something for another. I'll come back to you with this.

rollbear commented 3 years ago

I set up a CI matrix, and unsurprisingly it fails C++20 builds, exactly as you showed. Unfortunately your fix causes clang builds to fail because of incorrect use of an incomplete type. Apparently some other mechanism is needed to break the recursion.

rollbear commented 3 years ago

Solving this was trickier than I thought. C++20 introduced a new rule that if you have A::operator==(B), then B==A compiles by trying A==B, which caused the infinite recursion. Breaking this conditionally was tricky, especially since I also learned that compilers are unfaithful with the __cplusplus macro, so a preprocessor check did not work. MSVC still hates the code, but several clang++/g++ compiles it warning free in both C++17 and C++20 mode. Closing this now. Thank you for bringing this to my attention.

nebularnoise commented 3 years ago

Oof, I see you've had to jump through some hoops indeed !

Thanks for the fix, and for such a quick response :)