请考虑以下内容:
struct A {
A(int, int) { }
};
struct B {
B(A ) { } // (1)
explicit B(int, int ) { } // (2)
};
int main() {
B paren({1, 2}); // (3)
B brace{1, 2}; // (4)
}
在(4)中,brace
的构造清晰明确地调用了(2)
。在clang上,在(3)中,paren
的构造明确调用(1)
,而在gcc 5.2上,它不能编译,会出现以下错误:main.cpp: In function 'int main()':
main.cpp:11:19: error: call of overloaded 'B(<brace-enclosed initializer list>)' is ambiguous
B paren({1, 2});
^
main.cpp:6:5: note: candidate: B::B(A)
B(A ) { }
^
main.cpp:5:8: note: candidate: constexpr B::B(const B&)
struct B {
^
main.cpp:5:8: note: candidate: constexpr B::B(B&&)
哪个编译器是正确的?我怀疑clang是正确的,因为在gcc中的歧义只能通过涉及隐式构造B {1,2}
并将其传递给复制/移动构造函数的路径才能产生 - 然而,该构造函数标记为explicit
,因此不应允许进行这种隐式构造。