Section 9.4.2, Static Data Members, C ++ Standard States:
If the static data member is of type const integer or const enumeration, its declaration in the class definition may indicate a const initializer, which must be an integral constant expression.
Consequently, the value of a static data member can be included "inside the class" (by which I assume that you are referring to the class declaration). However, the type of the static data element must be an enum type const integer or const . The reason that the values โโof static data elements of other types cannot be specified in the class declaration is because non-trivial initialization is required (i.e., the constructor must be executed).
Imagine if the following rules were:
// my_class.hpp
Each object file corresponding to the CPP files that include this header will have not only a copy of the storage space for my_class::str (consisting of sizeof(std::string) bytes), but also a "ctor section" that calls std::string constructor with a C-string. Each copy of the storage space my_class::str will be identified using a common label, so the linker can theoretically merge all copies of the memory space into one. However, the linker will not be able to isolate all copies of the constructor code inside the ctor sections of the object files. This would be like a linker request to remove all the code to initialize str in compiling the following:
std::map<std::string, std::string> map; std::vector<int> vec; std::string str = "test"; int c = 99; my_class mc; std::string str2 = "test2";
EDIT It is instructive to look at the output of the g ++ assembler for the following code:
// SO4547660.cpp
The assembly code can be obtained by doing:
g++ -S SO4547660.cpp
Looking through the SO4547660.s file generated by g ++, you can see that there is a lot of code for such a small source file.
__ZN8my_class3strE is the storage space label my_class::str . There is also a source for the assembly of the __static_initialization_and_destruction_0(int, int) function, which is labeled __Z41__static_initialization_and_destruction_0ii . This function is specifically for g ++, but just know that g ++ will make sure that it is called before any code is run without an initializer. Note that the implementation of this function calls __ZNSsC1EPKcRKSaIcE . This is a garbled character for std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) .
Returning to the hypothetical example above and using this data, each object file corresponding to the CPP file that includes my_class.hpp will have the __ZN8my_class3strE label for sizeof(std::string) bytes, as well as the assembly code for calling __ZNSsC1EPKcRKSaIcE as part of the __static_initialization_and_destruction_0(int, int) function __static_initialization_and_destruction_0(int, int) . The compiler can easily combine all occurrences of __ZN8my_class3strE , but it cannot isolate the code that calls __ZNSsC1EPKcRKSaIcE in the implementation of the __static_initialization_and_destruction_0(int, int) object file.