Generally speaking you must define your static members in precisely one translation unit, and the language helps to enforce this by prohibiting you from writing an initialiser for such a member inside the surrounding class definition:
struct T
{
static int x = 42;
};
However, a special exception is made for constants, for convenience:
struct T
{
static const int x = 42;
};
Note that in most cases you still need to define the constant (in your .cpp file would be the best place):
const int T::x;
[C++11: 9.4.2/3]:]
If a non-volatile 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 (5.19). A static
data member of literal type can be declared in the class definition with the constexpr
specifier; if so, its declaration shall specify a brace-or-equal-initializer in which every initializer-clause that is an assignment-expression is a constant expression. [ Note: In both these cases, the member may appear in constant expressions. —end note ] The member shall still be defined in a namespace scope if it is odr-used (3.2) in the program and the namespace scope definition shall not contain an initializer.
Now, your member is not an int
and even a const char* const
is not of an "integral type":
struct T
{
static const char* const str = "hi";
};
but it is of a "literal type"; the upshot for you is that if you write it like this:
static constexpr const char* const xml_ID_TAG = "id";
you should be okay. (Note that you will still need to define it, until C++17.)
This probably makes more sense anyway: why would you want to change the pointer?
static const
integral members can be defined inside a class body. This is to prevent ODR violations. – Simple