I will summarize the rules for direct class initialization in C ++ 98 vs C ++ 11:
The following code is illegal in C ++ 03, but works the same as you would expect in C ++ 11. In C ++ 11, you can think of it as initializers injected into each of the POD constructors, unless that constructor sets other meaning.
struct POD { int integer = 42; float floating_point = 4.5f; std::string character_string = "Hello"; };
Creating fields that modify static members will break the code in both standards because static ensures that there will be only one copy of the variable, and therefore we must declare the members in exactly the same file, just as we will do with global variables using the aforementioned using the extern keyword.
// This does not work struct POD { static int integer = 42; static float floating_point = 4.5f; static std::string character_string = "Hello"; }; int POD::integer = 42; float POD::floating_point = 4.5f; std::string POD::character_string = "Hello"; // This works struct POD { static int integer; static float floating_point; static std::string character_string; }; int POD::integer = 42; float POD::floating_point = 4.3f; std::string POD::character_string = "hello";
If we try to create them, constant constant members will create a new array of rules:
struct POD { static const int integer = 42; // Always works static constexpr float floating_point = 4.5f; // Works in C++11 only. static const std::string character_string = "Hello"; // Does not work. constexpr static const std::string character_string = "Hello"; // Does not work (last checked in C++11) // Like some others have also mentioned, this works. static const std::string character_string; }; // In a sourcefile: const std::string POD::character_string = "Hello";
So, starting with C ++ 11, static constants of non-integer variables of trivial types are allowed. Strings, unfortunately, do not match the bill, so we cannot initialize constexpr std :: string even in C ++ 11.
Everything is not lost, although, as stated in this post , you can create string class functions as a string literal.
NB! Note that this is metaprogramming at best, if the object is declared as constexpr static inside the class, then as soon as you enter at run time, the object will not be found anywhere. I did not understand why, please feel free to comment on it.
// literal string class, adapted from: http://en.cppreference.com/w/cpp/language/constexpr class conststr { const char * p; std::size_t sz; public: template<std::size_t N> constexpr conststr(const char(&a)[N]) : p(a), sz(N-1) {} // constexpr functions signal errors by throwing exceptions from operator ?: constexpr char operator[](std::size_t n) const { return n < sz ? p[n] : throw std::out_of_range(""); } constexpr std::size_t size() const { return sz; } constexpr bool operator==(conststr rhs) { return compare(rhs) == 0; } constexpr int compare(conststr rhs, int pos = 0) { return ( this->size() < rhs.size() ? -1 : ( this->size() > rhs.size() ? 1 : ( pos == this->size() ? 0 : ( (*this)[pos] < rhs[pos] ? -1 : ( (*this)[pos] > rhs[pos] ? 1 : compare(rhs, pos+1) ) ) ) ) ); } constexpr const char * c_str() const { return p; } };
Now you can declare conststr directly in your class:
struct POD { static const int integer = 42; // Always works static constexpr float floating_point = 4.5f; // Works in C++11 only. static constexpr conststr character_string = "Hello"; // C++11 only, must be declared. }; int main() { POD pod; // Demonstrating properties. constexpr conststr val = "Hello"; static_assert(val == "Hello", "Ok, you don't see this."); static_assert(POD::character_string == val, "Ok"); //static_assert(POD::character_string == "Hi", "Not ok."); //static_assert(POD::character_string == "hello", "Not ok."); constexpr int compare = val.compare("Hello"); cout << compare << endl; const char * ch = val.c_str(); // OK, val.c_str() is substituted at compile time. cout << ch << endl; // OK cout << val.c_str() << endl; // Ok // Now a tricky one, I haven't figured out why this one does not work: // cout << POD::character_string.c_str() << endl; // This fails linking. // This works just fine. constexpr conststr temp = POD::character_string; cout << temp.c_str() << endl; }