In-Class Initialization Errors

Summary

In this post, I will introduce some common compiling errors I used to see related to in-class initialization:

  1. Error: in-class initialization of static data member xxx of non-literal type;
  2. 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:

  1. For static varibles, do not initialize them Inline;
  2. Always initialize static varibles in the source file;
  3. 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};
}

Leave a Reply

Your email address will not be published. Required fields are marked *