Motivated by this question1, I created the following code:
struct X {
X(int) {}
};
struct Y {
operator X() { return X{1}; }
operator int() { return 1; }
};
int main() {
X x(Y{});
}
Live demo with error messages.
This code:
throws an ambiguity error with all GCC and Clang versions (I have tried) if C++11/14 is enabled,
throws an ambiguity error with some GCC and Clang versions if C++17 is enabled (e.g., GCC 8.2, GCC 6.3, Clang 5),
compiles with some GCC and Clang version if C++17 is enabled (e.g., GCC 7.3, Clang 6).
The ambiguity stems from possible conversions:
Y
→X
,Y
→int
andint
→X
,
since the compiler does not know which constructor of X
it should use (copy/move or converting from int
).
I wonder why there is such discrepancy in compilers behavior and whether the Standard says that this code should trigger an error or not.
1 Note that this is not a duplicate. In the linked question, OP asked about how to remove ambiguity. I ask why the behavior is different with different compilers.