Mihai Galos
Mihai Galos

Reputation: 1897

Statically initializing constexpr std::array of objects containing function pointers

I am trying to statically initialize a constexpr std::array of objects containing function pointers with the following code:

#include <array>

using TVoidVoid = void(*)(void);

class State{
public:
  constexpr State(TVoidVoid function) : function_{function}{}
private:
  TVoidVoid function_;
};

void OnEvent1(){}
void OnEvent2(){}
constexpr std::array<State, 10> states = {{OnEvent1}, {OnEvent2}};

int main(){}

I am compiling with:

g++ -Wall -Wextra -Wshadow -Weffc++ -Wstrict-aliasing -ansi -pedantic -Werror -std=c++14 main.cpp

I have trouble understanding the compiling error I'm getting:

main.cpp:14:69: error: too many initializers for ‘const std::array<State, 10>’
 constexpr std::array<State, 10> states = {{OnEvent1}, {OnEvent2}}

The compiler is g++ (Ubuntu 7.3.0-27ubuntu1~18.04) 7.3.0.

What could be the problem here? Many thanks in advance!

Upvotes: 1

Views: 165

Answers (2)

Mirko
Mirko

Reputation: 1083

You need a default constructor (for the last 8)

#include <array>

using TVoidVoid = void(*)(void);

class State{
public:
  // This static is equivalent to a TVoidVoid
  // used by the default constructor
  static void DefFunct() {}

  constexpr State(TVoidVoid function) : function_{function}{}

  // We create a default constructor for the 
  // empty elemnts of the array with our function
  constexpr State() : function_(DefFunct) {}

private:
  TVoidVoid function_;
};

void OnEvent1(){}
void OnEvent2(){}
constexpr std::array<State, 10> states = {OnEvent1, OnEvent2};

int main(){}

Upvotes: 1

The error message could be better. But what's tripping the initialization is in fact that you don't have enough braces. Recall that a std::array is an aggregate wrapping a raw array. So you need to initialize like this:

constexpr std::array<State, 10> states = {{ {OnEvent1}, {OnEvent2} }};

Otherwise, the somewhat inaccurate brace ellision detection algorithm assumes {OnEvent1} is to initialize the internal array, and the second clause is redundant.

Now you just need to provide a default c'tor for State, or adjust the array size.

Upvotes: 2

Related Questions