-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
error: conversion from ‘int’ to ‘const snapdev::timespec_ex’ is ambiguous #2571
Comments
And here I was, thinking that the decomposing rewrite has gone fine. 😃 I understand what the issue is, and I think I know how to fix it. |
I couldn't reproduce this locally, turns out that this only happens with older versions of GCC. |
Okay, in that case it's certainly not too important. Ubuntu 18.04 will soon be out of date so it's probably not worth the trouble. Up to you if you want to just close this issue. |
This is needed so that we can use conjunction and other logical type traits to workaround issue with older GCC versions (8 and below), when they run into types that have ambiguous constructor from `0`, see e.g. #2571. However, using conjunction and friends in the SFINAE constraint in the template parameter breaks for C++20 and up, due to the new comparison operator rewriting rules. With C++20, when the compiler see `a == b`, it also tries `b == a` and collects overload set for both of these expressions. In Catch2, this means that e.g. `REQUIRE( 1 == 2 )` would lead the compiler to check overloads for both `ExprLhs<int> == int` and `int == ExprLhs<int>`. Since the overload set and SFINAE constraints assume that `ExprLhs<T>` is always on the left side, when the compiler tries to resolve the template parameters, all hell breaks loose and the compilation fails. By moving the SFINAE constraints to the return type, the compiler can discard the switched expression without having to resolve the complex SFINAE constraints, and thus everything works the way it is supposed to. Fixes #2571
Well, this turned out to be quite the journey. The workaround for old GCC worked fine pre C++20, which significantly changed the rules for comparison operators, in a way that was incompatible with the workaround (but worked without the workaround due to SFINAE rules). The current |
Excellent. That worked in my environment as well. So you fixed it! :-) |
Describe the bug
I have a class named
snapdev::timespec_ex
with several constructors. The two we are concerned with here are:which cause an issue when I try to do:
because you have a macro which has this declaration (
catch2/internal/catch_compare_traits.hpp
):I think that the value
0
should be taken as anstd::int64_t
, but in this case the compiler decides thatdouble
is also a viable choice. Here is the error:Expected behavior
I expect the code to compile as before.
Reproduction steps
Extract the test.cpp file, see the c++ command line at the top of the file. Just add a
-I ...
path if you do not have catch2 under/usr/include
.test.zip
Platform information:
Additional context
It was working fine with the previous version (3.1.1).
Temporary Fix
As shown in the attached
test.cpp
file, I can just add a new constructor acceptingint
and it compiles just fine. I would prefer not to have that operator as it is likely to cause very difficult to find bugs.Reference
For reference, the original is found in the
snapdev
project. The file is namedsnapdev/timespec_ex.h
. The corresponding test,tests/catch_timespec_operations.cpp
is what generates the errors.The text was updated successfully, but these errors were encountered: