Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c++ explicit multi-arg constructor ambiguity

Tags:

c++

c++11

I'm encountering an unexpected issue in some code I'm writing now and I'm not sure which compiler is correct.

We have a multi-argument constructor which takes const char*, const char*, but it is declared explicit:

constexpr explicit Wrapper(const char* a, const char* b)  : pair(a,b){}

And then we have a function which takes Wrapper and an overload which takes a std::pair<const char*, const char*>

void q(Wrapper w);
void q(std::pair<const char *, const char *> w);

And then we have code like this, which I would expect to call the second overload:

q({"a", "b"});

This compiles fine on clang, but fails to compile on both GCC and MSVC. I've been trying to look for any mention of explicit multi-arg constructor in the standard and if there's anything mentioning this ambiguity but I haven't found the relevant text. I'm just wondering which behavior is correct and which is wrong?

godbolt link: https://godbolt.org/g/2aYUov

like image 594
Morten242 Avatar asked Jul 25 '17 08:07

Morten242


1 Answers

Using your provided constructor for Wrapper, g++ 7.1.1 gives me the following error:

main.cpp: In function ‘int main()’:
main.cpp:29:25: error: converting to ‘Wrapper’ from initializer list would use explicit constructor ‘constexpr Wrapper::Wrapper(const char*, const char*)’
     Wrapper w({"a", "b"});
                         ^

So it seems that the explicit keyword on the Wrapper constructor is well taken into account when manually triggering a conversion.

However, the error on the call to q seems to indicate that overload resolution is ignoring the explicit keyword:

main.cpp:34:17: error: call of overloaded ‘q(<brace-enclosed initializer list>)’ is ambiguous
     q({"a", "b"});
                 ^
main.cpp:16:6: note: candidate: void q(Wrapper)
 void q(Wrapper w)
      ^
main.cpp:21:6: note: candidate: void q(std::pair<const char*, const char*>)
 void q(std::pair<const char *, const char *> w)
      ^

This could be a bug in g++, which would need to be verified with other sources.

like image 91
Gunee Avatar answered Oct 17 '22 05:10

Gunee