Decision:
std::array<SomeThing, 64> SomeThing::lookup_table_0 {{ }};
Note: as described here , <21_value> needs to initialize the value of std::array without warning in gcc. = {} and {} are correct, but gcc warns you anyway.
The key to the solution is to have some form of initializer.
First, the terminology is checked: all objects are initialized in C ++. There are three forms: default value, value and zero. There are no "uninitialized" objects; objects without an explicit initializer are called initialized by default. In some cases, this means that the member variables of the object may be undefined ("garbage").
What is the problem with a version without an initializer? First, the constructor for std::array<SomeThing, 64> is defined as deleted because the declaration is std::array<SomeThing, 64> x; will be poorly formed (due to the lack of an accessible default constructor for SomeThing , of course).
This means that any code that tries to use the default constructor for std::array<SomeThing, 64> , in turn, is poorly formed. Definition:
std::array<SomeThing, 64> SomeThing::lookup_table_0;
tries to use the default constructor, so it is poorly formed. However, once you start introducing initializers, the default constructor for std::array no longer plays the game; since std::array is an aggregate, then aggregate initialization occurs, which bypasses the implicitly generated constructor (s). (If there were any user-declared constructors, this would no longer be an aggregate).
The initializer version works because of [dcl.init] / 13 (n3936):
The initializer for the static member is in the scope of the member class
The definition of conversion-initialization of the list { } to { SomeThing() } here.