Summary
In this post, I will introduce some common compiling errors I used to see related to in-class initialization:
- Error: in-class initialization of static data member xxx of non-literal type;
- Error: ISO C++ forbids in-class initialization of non-const static member xxx;
Conclusion
As usual, I present the correct ways to do in-class initialization at the very beginning.
// header.h
class Base {
public:
static int count;
static char const static_char = 'a';
static int const static_int = 1;
static constexpr std::pair<int, int> static_constexpr_pair = {0, 1};
static std::string static_var;
static std::string const static_const_var;
std::string const const_var = "const_var";
std::vector<int> const const_vec = {0, 1, 2};
Base() {
count++;
}
};
// src.cpp
int Base::count = 0;
std::string Base::static_var = "static_var";
std::string const Base::static_const_var = "static_const_var";
Some golden rules we can follow are:
- For static varibles, do not initialize them Inline;
- Always initialize static varibles in the source file;
- You can do any kind of inline initialization for non-static variable.
Details
Why I can’t initialize static data members in class?
You will get "Error: in-class initialization of static data member xxx of non-literal type" in the following codes.
class Base {
public:
static std::string static_var = "static_var";
static std::string const static_const_var = "static_const_var";
}
Bjarne explains this aptly here:
"A class is typically declared in a header file and a header file is typically included into many translation units. However, to avoid complicated linker rules, C++ requires that every object has a unique definition. That rule would be broken if C++ allowed in-class definition of entities that needed to be stored in memory as objects."
Inline initialization of static member variables
There are a few shortcuts to the above. First, when the static member is a const integral type (which includes char and bool) or a const enum, the static member can be initialized inside the class definition:
// header.h
class Base {
public:
static char const static_char = 'a';
static int const static_int = 1;
}
The reason is "Static const integers (and enums) can be treated as compile-time constants, so the compiler can replace calls to the const integer with the value itself."
Second, as of C++11, static constexpr members of any type that supports constexpr initialization can be initialized inside the class definition:
class Base {
public:
static constexpr std::pair<int, int> static_constexpr_pair = {0, 1};
}