1

I want to run this code:

struct A {
    static const string d[] = {"1", "2"};    
};

And get an error:

error: in-class initialization of static data member ‘const string A::d []’ of incomplete type
     static const string d[] = {"1", "2"};
                         ^
error: non-constant in-class initialization invalid for non-inline static member ‘A::d’
     static const string d[] = {"1", "2"};
                                        ^
note: (an out of class initialization is required)

Here I find information that now I can initialize what I want. So what the problem?

If I add inline then it will work:

struct A {
    static const inline string d[] = {"1", "2"};    
};

UPD: I know the solves but why c++ works like that?

dasfex
  • 1,148
  • 2
  • 12
  • 30

2 Answers2

1

As you noticed you can either use inline or the following:

struct A {
    static const string d[];    
};

and

const string A::d[] = {"1", "2"};

in a dedicated compilation unit (once only).

Live Demo

πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
1

The standard explicitly states that non-inline static data members of a class are declaration only, and must be followed up by definition at namespace scope: class.static.data#3

3: The declaration of a non-inline static data member in its class definition is not a definition and may be of an incomplete type other than cv void. The definition for a static data member that is not defined inline in the class definition shall appear in a namespace scope enclosing the member's class definition. In the definition at namespace scope, the name of the static data member shall be qualified by its class name using the ​::​operator. The initializer expression in the definition of a static data member is in the scope of its class ([basic.scope.class]).

These rules are then refined further so that non-volatile non-inline const static data member of integral or enumeration type can be brace initialised (in effect defining the variable at the point of declaration): class.static.data#4

4: If a non-volatile non-inline const static data member is of integral or enumeration type, its declaration in the class definition can specify a brace-or-equal-initializer in which every initializer-clause that is an assignment-expression is a constant expression ([expr.const]). The member shall still be defined in a namespace scope if it is odr-used ([basic.def.odr]) in the program and the namespace scope definition shall not contain an initializer. An inline static data member may be defined in the class definition and may specify a brace-or-equal-initializer.

In non-standardese speak, this says that you must define static member variables separately from the definition except for the case of integers or enums, which explains why your example fails.

Antony Peacock
  • 449
  • 4
  • 8