c ++显式多arg构造函数歧义

时间:2017-07-25 08:15:21

标签: c++ c++11

我正在编写一些我现在正在编写的代码中的意外问题而且我不确定哪个编译器是正确的。

我们有一个多参数构造函数,它接受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上编译。我一直试图在标准中寻找任何明确的多arg构造函数的提及,如果有什么提到这种歧义,但我没有找到相关的文本。我只是想知道哪种行为是正确的,哪种行为是错的?

godbolt链接:https://godbolt.org/g/2aYUov

1 个答案:

答案 0 :(得分:2)

使用您提供的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构造函数上的explicit关键字。

然而,调用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 ++中的一个错误,需要与其他来源进行验证。