The following code, a simplified version of code found in the googlemock project, fails to compile in Visual Studio 2015 Update 1, but it compiles on clang [Apple LLVM version 7.0.0 (clang-700.1.76)].
struct ConvertibleFromAny { ConvertibleFromAny(int a_value); template <typename T> ConvertibleFromAny(const T& a_value); }; template <typename T> struct Matcher { Matcher(T value); }; template <typename Rhs> struct EqMatcher { explicit EqMatcher(const Rhs& rhs); template <typename Lhs> operator Matcher<Lhs>() const; }; int main() { EqMatcher<ConvertibleFromAny> em(1); Matcher<ConvertibleFromAny> m = em; return 0; }
The error occurs at the assignment statement
Matcher<ConvertibleFromAny> m = em;
and the error message is
error C2440: 'initializing': cannot convert from 'EqMatcher<ConvertibleFromAny>' to 'Matcher<ConvertibleFromAny>' note: No constructor could take the source type, or constructor overload resolution was ambiguous
I can naively see an ambiguity between a member call to
EqMatcher<ConvertibleFromAny>::operator Matcher<ConvertibleFromAny>()
and an initialization conceptually similar to
Matcher<ConvertibleFromAny> m(ConvertibleFromAny<EqMatcher<ConvertibleFromAny>>(em))
My guess is that clang rules out the second option.
EDIT: Inspired by T.C.'s comment I tested the following:
struct A { }; struct X { X(const A&); }; struct B { B(const X&); }; int main() { A a; B b = a; }
It compiles with VS 2015, but not with clang. I have not been able to find any references that documents that the Visual C++ implementation intentionally deviates from the standard in this regard.
Is this a well-known problem?
Both your code samples produce the expected result with VS2015 Update 1, if I enable the "Disable Language Extensions" (/Za
) flag. That is, the first one compiles, the second one does not.
I'm not sure which extension in particular is interfering here, though. I found this MSDN page: Microsoft Extensions to C and C++, but it does not appear to be complete - for example, binding a non-const T& to an rvalue is not mentioned.
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