Question:
#include <iostream>
using std::cout;
using std::endl;
template <unsigned int i>
struct Fibo{
static const unsigned result = Fibo<i-1>::result + Fibo<i-2>::result;
};
template <>
struct Fibo<0>{
static const unsigned result = 1;
};
template <>
struct Fibo<1>{
static const unsigned result = 1;
};
int main () {
cout << Fibo<5>::result << endl;
return 0;
}
If the const modifier is removed, the compiler declares
error: non-const static data member must be initialized out of line
Answer:
Static data members need an initialization outside the class declaration. That is:
struct S {
static int i;
};
int S::i = 42; // definição
This is a language restriction, following the one definition rule, or ODR. The constraint exists to prevent two or more initializations from existing for the static member S::i
(for example, if the class is included in two distinct translation units). Note: Initialization only needs to appear in one translation unit, otherwise the behavior is undefined.
With the const
qualifier, standardization allows you to initialize the static member to some constant expression (that is, you can initialize to a literal like 42
, but you cannot initialize to some value that does not result in a constant expression).
In c++17 it is possible to use the inline
specifier to allow initialization of the data member in the same location as its declaration:
struct S {
static inline int i = 42;
};
Here, inline
has the same effect when applied to functions: its initialization can appear in one or more translation units (as long as they are equivalent, eg included by a #include
directive) and only one of them will actually be used.