C++ 显式多参数构造函数歧义

c++ explicit multi-arg constructor ambiguity

本文关键字:构造函数 歧义 参数 C++      更新时间:2023-10-16

我现在正在编写的某些代码中遇到了意外问题,我不确定哪个编译器是正确的。

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

神霹雳链接:https://godbolt.org/g/2aYUov

使用您提供的包装器构造函数,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++ 中的一个错误,需要用其他来源进行验证。