why the following code does not compile, and when I delete the explicit keyword before the constructor in class A, does it compile?
Using Visual Studio 2013:
enum E { e1_0, e1_1 }; template<typename T> struct A { A() {} explicit A(unsigned long) {} A(T) {} }; struct B { B() {} B(E) {} }; void F(B) {}; void F(A<short>) {}; void test() { F(e1_0); }
Error:
1>------ Build started: Project: exp_construct_test, Configuration: Debug Win32 ------ 1> exp_construct_test.cpp 1>e:\exp_construct_test\exp_construct_test.cpp(23): error C2668: 'F' : ambiguous call to overloaded function 1> e:\exp_construct_test\exp_construct_test.cpp(19): could be 'void F(A<short>)' 1> e:\exp_construct_test\exp_construct_test.cpp(18): or 'void F(B)' 1> while trying to match the argument list '(E)' ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
Edit: I downloaded clang and compiled clang-cl, which reports an error for both cases. As noted in the comments, the ambiguity is between A<short>(short) and B(E) .
So maybe there is a mistake in VC ++: when I remove explicit from A(unsigned long) , the compiler, by some intention, chooses B (E) instead of raising an ambiguity error. Can someone confirm the behavior of clang as standard, and VC ++ - buggies?
I added
void G(E) {}; void G(short) {};
and call in G:
G(e1_0);
This does not cause any errors. Why is G(E) taught here, and in the case of candidates A<short>::A(short) and B::B(E) are they ambiguous?
Edit end
Thanks --joja
source share