2012-02-05 207 views
7

尽管我非常喜欢C++ 11中的新功能,但有时候我觉得我错过了它的一些微妙之处。std ::数组初始化列表在初始化列表中初始化

初始化int数组工作正常,初始化Element2向量工作正常,但初始化Element2数组失败。我认为正确的语法应该是未注释的行,但没有任何初始化尝试对我成功。

#include <array> 
#include <vector> 

class Element2 
{ 
    public: 
      Element2(unsigned int Input) {} 
      Element2(Element2 const &Other) {} 
}; 

class Test 
{ 
    public: 
      Test(void) : 
        Array{{4, 5, 6}}, 
        Array2{4, 5}, 
        //Array3{4, 5, 6} 
        Array3{{4, 5, 6}} 
        //Array3{{4}, {5}, {6}} 
        //Array3{{{4}, {5}, {6}}} 
        //Array3{Element2{4}, Element2{5}, Element2{6}} 
        //Array3{{Element2{4}, Element2{5}, Element2{6}}} 
        //Array3{{{Element2{4}}, {Element2{5}}, {Element2{6}}}} 
        {} 
    private: 
      std::array<int, 3> Array; 
      std::vector<Element2> Array2; 
      std::array<Element2, 3> Array3; 
}; 

int main(int argc, char **argv) 
{ 
    Test(); 
    return 0; 
} 

我已经在MinGW下的g ++ 4.6.1和4.6.2上试过了。

我应该如何正确地去初始化这个数组?可能吗?

+0

我想这与初始化列表没有太大的关系。编辑问题以使其更切合实际是否合适? – rendaw 2012-02-05 03:57:12

回答

6

对此的正确方法是Array{{4, 5, 6}}。当您使用集合初始化初始化成员时,不能省略大括号。你可以忽略括号中的唯一的一次是在形式

T t = { ... } 

所以你的情况,你必须键入的所有大括号的声明:一为std::array本身,以及一个用于int阵列。对于Array3,您的语法也是正确的,因为int可以隐式转换为Element2

从剩下的评论者中,Array3{{{4}, {5}, {6}}},Array3{{Element2{4}, Element2{5}, Element2{6}}}Array3{{{Element2{4}}, {Element2{5}}, {Element2{6}}}}也可以工作,但更罗嗦。然而,在概念上Array3{{{4}, {5}, {6}}}一个产生最少数量的临时实施不做复制elision(我猜这是无关的,但仍然很好知道),甚至比Array3{{4, 5, 6}}一个,因为不是复制初始化你使用复制列表初始化为您的Element2,它不会产生中间临时设计

+0

你是说它应该可以正常工作,并且GCC坏了?因为OP在说所有这些变化都失败了。另外,这是如何工作的,因为'std :: array '不是一个聚合?我可以引用规范的聚合要求,而'std :: array '没有通过测试。你能否引用关于如何通过聚合初始化来初始化非聚集的规范?我不是说你错了。我毫不犹豫地承认我从未完全阅读过C++ 11规范。同时,我希望您的声明的真实性有一些证据。 – 2012-02-05 15:29:19

+1

@NicolBolas据我所知,'std :: array '是一个聚合体:它是一个没有用户定义的构造函数的结构 - 它在''的描述中被明确提及为聚合体。 – hvd 2012-02-05 19:24:16

+0

@nico什么hvd说 – 2012-02-05 19:32:39