Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

std::array initializer list initialization in initialization list

Although I much enjoy the new features in C++11, sometimes I feel like I'm missing some of its subtleties.

Initializing the int array works fine, initializing the Element2 vector works fine, but initializing the Element2 array fails. I think the correct syntax should be the uncommented line, but none of the initialization attempts have succeeded for me.

#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;
}

I've tried this on g++ 4.6.1 and 4.6.2 under MinGW.

How should I correctly go about initializing this array? Is it possible?

like image 361
rendaw Avatar asked Feb 05 '12 02:02

rendaw


1 Answers

The correct way to go about this is Array{{4, 5, 6}}. You cannot omit braces when you initialize a member with aggregate initialization. The only time you can omit braces is in a declaration of the form

T t = { ... }

So in your case you have to type out all braces: One for the std::array itself, and one for the int array. For Array3, your syntax is correct too, since int can be converted to Element2 implicitly.

From the remaining commented ones, the Array3{{{4}, {5}, {6}}}, Array3{{Element2{4}, Element2{5}, Element2{6}}} and Array3{{{Element2{4}}, {Element2{5}}, {Element2{6}}}} work too, but are more wordy. However conceptionally the Array3{{{4}, {5}, {6}}} one produces the least amount of temporaries on implementations that don't do copy elision (I guess that's irrelevant, but still good to know), even less than the Array3{{4, 5, 6}} one, because instead of copy initialization you use copy list initialization for your Element2, which doesn't produce an intermediary temporary by design.

like image 86
Johannes Schaub - litb Avatar answered Sep 20 '22 10:09

Johannes Schaub - litb