С++ явная множественная конструкция конструктора неоднозначность

Я сталкиваюсь с неожиданной проблемой в некотором коде, который я пишу сейчас, и я не уверен, какой компилятор прав.

У нас есть конструктор с несколькими аргументами, который принимает const char*, const char*, но он объявлен явным:

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

И тогда у нас есть функция, которая принимает Wrapper и перегрузку, которая принимает std::pair<const char*, const char*>

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

И тогда у нас есть такой код, который я бы назвал второй перегрузкой:

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

Это компилируется на clang, но не компилируется как на GCC, так и на MSVC. Я пытался найти упоминание явного конструктора multi-arg в стандарте, и если что-то упоминает эту двусмысленность, но я не нашел соответствующий текст. Мне просто интересно, какое поведение правильное и что неправильно?

ссылка godbolt: https://godbolt.org/g/2aYUov

Ответы

Ответ 1

Используя предоставленный конструктор для Wrapper, g++ 7.1.1 дает мне следующую ошибку:

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"});
                         ^

Итак, кажется, что явное ключевое слово в конструкторе Wrapper хорошо учитывается при ручном запуске преобразования.

Однако ошибка при вызове q указывает, что разрешение перегрузки игнорирует явное ключевое слово:

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)
      ^

Это может быть ошибка в g++, которая должна быть проверена другими источниками.