15

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

Dev Null
  • 4,731
  • 1
  • 30
  • 46
Morten242
  • 139
  • 1
  • 13

1 Answers1

2

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.

Gunee
  • 431
  • 3
  • 16