I encounter an issue, that is hard to explain for me. Here is the minimal, reproducible code, that is failing on both GCC 6.2 and Clang 3.9:
class T2;
class T1
{
int field1;
public:
T1(int pf) : field1(pf) {}
operator int() { return field1; }
operator T2();
};
class T2
{
int field2;
public:
T2(int pf) : field2(pf) {}
};
T1::operator T2() { return T2(field1); }
void foo(T2 pt) {}
int main()
{
T1 obj1(1);
T2 obj2(2);
foo((T2) obj1); // ambiguous conversion for C-style cast from 'T1' to 'T2'
foo(T2(obj1)); // ambiguous conversion for functional-style cast from 'T1' to 'T2'
foo(static_cast<T2>(obj1)); // ambiguous conversion for static_cast from 'T1' to 'T2'
}
Note that I didn't write the specific constructor to convert from T1 to T2, so I guess it should be all clear to the compiler, that the only way is to use user defined cast operator.
The curious fact is that when I comment out a seemingly unrelated cast operator:
// operator int() { return field1; }
then the code compiles hassle-free. What is the reason for that?
(T2) obj1 means exactly the same thing as T2(obj1) (or static_cast<T2>(obj1) in this case), but maybe it'll be easier to reason about this constructor-like syntax.
With the code as-is, there are two options:
T2 with an int, obtained by the user-defined conversion operator to intT2 from T2 obtained by the user-defined conversion operator to T2As per N4140:
If there is exactly one viable function that is a better function than all other viable functions, then it is the one selected by overload resolution; otherwise the call is ill-formed
Two implicit conversion sequences of the same form are indistinguishable conversion sequences unless one of the following rules applies:
- User-defined conversion sequence
U1is a better conversion sequence than another user-defined conversion sequenceU2if they contain the same user-defined conversion function or constructor or they initialize the same class in an aggregate initialization and in either case the second standard conversion sequence ofU1is better than the second standard conversion sequence ofU2.
Since this doesn't apply, neither conversion is better than the other.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With