我认为这答案可能相关 https://stackoverflow.com/a/9723448/1508519.
是的,根据 §13.3.1.7 初始化,此行为是有意的
通过列表初始化
当非聚合类类型 T 的对象被列表初始化时 (8.5.4),重载决策分两个阶段选择构造函数:
— 最初,候选函数是类 T 的初始化列表构造函数(8.5.4),参数列表包括
初始化列表作为单个参数。
— 如果没有找到可行的初始化列表构造函数,则再次执行重载决策,其中候选函数全部为
类 T 的构造函数和参数列表由以下组成
初始化列表的元素。
In gcc
我试过你的例子。我收到此错误:
error: call of overloaded 'A(<brace-enclosed initializer list>)' is ambiguous
gcc
如果我使用三套支架,就不再抱怨了。 IE。:
#include <iostream>
#include <vector>
#include <initializer_list>
struct A {
A (std::initializer_list<int> il) {
std::cout << "First." << std::endl;
}
A (std::initializer_list<std::initializer_list<int>> il) {
std::cout << "Second." << std::endl;
}
};
int main()
{
A a{0}; // first
A a{{0}}; // compile error
A a2{{{0}}}; // second
A a3{{{{0}}}}; // second
}
为了镜像向量的构造函数,以下是我的结果:
#include <iostream>
#include <vector>
#include <initializer_list>
struct A {
A (std::initializer_list<int> il) {
std::cout << "First." << std::endl;
}
explicit A (std::size_t n) {
std::cout << "Second." << std::endl;
}
A (std::size_t n, const int& val) {
std::cout << "Third." << std::endl;
}
A (const A& x) {
std::cout << "Fourth." << std::endl;
}
};
int main()
{
A a{0};
A a2{{0}};
A a3{1,2,3,4};
A a4{{1,2,3,4}};
A a5({1,2,3,4});
A a6(0);
A a7(0, 1);
A a8{0, 1};
}
main.cpp:23:10: warning: braces around scalar initializer
A a2{{0}};
^~~
1 warning generated.
First.
First.
First.
First.
First.
Second.
Third.
First.