阅读当前C++1y草案标准。
从表99之前:
如果T能够通过零个或多个参数args从args中进行Emplace构造,则表示以下表达式是符合规范的: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]
从作为传递给 std::vector<double[3]>
的初始化列表的元素的 {1,2,3}
中的 EmplaceConstructible
。
关于前向迭代器也有一个条款,但这没有问题(因为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});
是放置 new 操作符,如果没有适当的
construct
覆盖,
EmplaceConstructable
将无法编译。因此,
double[3]
既不是从
std::initalizer_list<double>
中构建的
EmplaceConstruble
,也不是从
double[3]
或其他任何东西中构建的(由于我在放置 new 中使用了括号而导致错误),除非分配器进行了我不知道的魔法以避免放置 new。因此,你的代码违反了当前的草案标准,可能违反了 C++11,并且肯定违反了 C++03(对容器有更严格的要求)。
arr{{{ 10, 11,12}, {20, 21,22}}}
吗? - Lev Landau