给定一个类A
有两个构造函数,取 initializer_list<int>
和 initializer_list<initializer_list<int>>
分别,那么
A v{5,6};
调用前者,并且
A v{{5,6}};
正如预期的那样调用后者。 (clang3.3,显然 gcc 的行为不同,请参阅答案。标准要求什么?)
但是如果我删除第二个构造函数,那么
A v{{5,6}};
仍然编译,它使用第一个构造函数。我没想到会这样。我以为
A v{5,6}
将是访问 initializer_list<int>
的唯一方法构造函数。(我在玩
std::vector
和 this question I asked on Reddit 时发现了这一点,但我创建了自己的 A 类以确保它不仅仅是 std::vector
接口(interface)的怪癖。)
最佳答案
我认为这是 answer might be relevant .
Yes, this behaviour is intended, according to §13.3.1.7 Initialization by list-initialization
When objects of non-aggregate class type T are list-initialized (8.5.4), overload resolution selects the constructor in two phases:
— Initially, the candidate functions are the initializer-list constructors (8.5.4) of the class T and the argument list consists of the initializer list as a single argument.
— If no viable initializer-list constructor is found, overload resolution is performed again, where the candidate functions are all the constructors of the class T and the argument list consists of the elements of the initializer list.
在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 }
为了反射(reflect)向量的构造函数,这是我的结果:#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.
关于c++11 - 为什么 `vector<int> v{{5,6}};` 有效?我以为只允许一对 {}?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20714273/