'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 |
