'How can I initialise a member std::array of objects that don't have a default constructor?

Here's the code that I have a problem with:

class Foo {
public:
    Foo() :
        memberArray{Bar(1), Bar(3), Bar(2)}
    {}
    struct Bar {
        Bar(int param1) {  }
    };
private:
    std::array<Bar,3> memberArray;
//  Bar memberArray[3];    // Using a raw array like this instead compiles fine..
};

I'm using GCC 4.6.1, and compiling for c++11. How should I initialise my std::array?



Solution 1:[1]

Since array<T, N> is actually a struct, the fully braced version needs {{ .. }} (the inner ones are for the array member of the array<T, N> object). The spec does not allow brace elision here. It only allows it in a declaration of the form

Type var = { ... };

So you have to use fully braced syntax

Foo() :
    memberArray{{Bar(1), Bar(3), Bar(2)}}
{}

This is not a GCC bug, but required by the spec.

Solution 2:[2]

As a workaround, you can have a function return an instance of this array.

#include <array>

class Foo {
public:
    Foo() :
        memberArray(makeMemberArray())
    {}
    struct Bar {
        Bar(int param1) {  }
    };
private:
    std::array<Bar,3> memberArray;
//  Bar memberArray[3];    // Using a raw array like this instead compiles fine..

    static std::array<Bar, 3> makeMemberArray() { 
      std::array<Bar,3> a = {Bar(1), Bar(2), Bar(3)}; 
      return a; 
    }
};

I think uniform initialization is supposed to allow what you are doing, except it might not be implemented by the compiler.

Solution 3:[3]

Building on Johannes Schaub - litb's answer... at least GCC will allow you to use an abbreviated syntax (leaving out the, pointless, class name):

Foo() :
    memberArray{{ {1}, {3}, {2} }}
{}

instead of

Foo() :
    memberArray{{Bar(1), Bar(3), Bar(2)}}
{}

I, personally, only use something like the second version when I'm initializing an array of polymorphic pointers:

Foo() :
    memberArray{{
        dynamic_cast<Bar*>(new BarA(1)),
        dynamic_cast<Bar*>(new BarB(3)),
        dynamic_cast<Bar*>(new BarC(2))
    }}
{}

Solution 4:[4]

#include <stdio.h>
#include <array>
#include <iostream>

void test1(){ printf("hello 0\n");}
void test2(){printf("hello 1\n");}
void test3(){printf("hello 2\n");}



typedef void (*functionPointerType)(); //from fastled demoreel100 was   typedef void (*SimplePatternList[])();

    void (*functptr[])() = { test1, test2, test3 } ; //classic way
    std::array<functionPointerType, 3> funcList{ {test1, test2, test3} }; //  double-braces required in C++11 prior to




class FuncContainClass {
public:
std::array<functionPointerType, 3> funcList; 


};

FuncContainClass funcClass;

int main()
{

funcClass.funcList[1] = &test2;
funcClass.funcList[1]();



functptr[0]();

std::cout << funcList.size() << std::endl;
funcList[1]();
    return 0;
}

`

I found this post because I was simply trying to have an std::array of functions but I think I found a solution to this problem as well. I found if I created a typeDef of the function pointer it worked.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Johannes Schaub - litb
Solution 2 UncleBens
Solution 3 Compholio
Solution 4 Dorian Tolman