我正在为 POD、STL 和复合类型(如数组)开发小型(漂亮)打印机。在这样做的同时,我也在摆弄初始化列表并遇到以下声明
std::vector<double[3]> arr{ { 10, 11, 12 }, { 20, 21, 22 } };
似乎 VC2013 和 G++ 4.8 都不太满意并发出一致的错误消息,这两种情况对我来说都不是很有帮助
对于 VC++: 错误 C3074:数组只能用初始化列表初始化
对于 G++ 4.8: 错误:必须使用大括号括起来的初始化来初始化数组
所以要么不能在这里使用初始化列表,要么我的语法不正确?
在类似的方面,以下语法似乎是有效的
std::vector<std::array<int, 3>> arr{ { 10, 11, 12 }, { 20, 21, 22 } };
我的初始化列表可能有什么问题?
- 注意 我知道我应该使用
std::array
而不是 C 类型数组,但我只是在试验。 - 注意 如果你不想玩这个,这里有一个 IDEONE版本
- 注意另外,如果你能将我推荐回标准,那将是非常有益的。
最佳答案
阅读current C++1y draft standard .
从表 99 之前:
T is EmplaceConstructible into X from args , for zero or more arguments args , means that the following expression is well-formed: allocator_traits::construct(m, p, args)
表 100:
X(il); | Equivalent to | X(il.begin(), il.end());
--------------------+---------------------+--------------------------------
X(i, j); | | Requires:
X a(i, j); | | T shall be EmplaceConstructible
| into X from *i.
所以 std::vector<double[3]> v{ {1,2,3}, {4,5,6} };
有效当且仅当 double[3]
是EmplaceConstructible
来自 {1,2,3}
作为传递给 std::vector<double[3]>
的初始化列表的元素.
还有一个关于前向迭代器的子句,但这没问题(因为 std::initialzier_list
迭代器是前向迭代器)。
std::vector<T>
需要 std::initializer_list<T>
参数。
所以 std::initializer_list<double[3]>
是候选列表。
首先,std::initializer_list<double[3]> x = {{1.0, 2.0, 3.0}};
在 gcc 中编译失败。但假设这是 gcc 中的错误。
第二,::new (nullptr) double[3](std::initializer_list<double>{1.0, 2.0, 3.0});
放置新的,EmplaceConstructable
减少到缺乏合适的construct
重写,编译失败。
所以 double[3]
不是 EmplaceConstruble
来自std::initalizer_list<double>
也不来自 double[3]
也没有别的(因为错误发生是因为我使用了括号,而不是因为括号中的内容,在新的位置),除非分配器做了我不知道的魔法来避免新的位置。
因此您的代码违反了当前的标准草案,可能还违反了 C++11,当然还有 C++03(对容器有更严格的要求)。
关于c++ - 错误 C3074 : an array can only be initialized with an initializer-list,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25330525/