I have this question bugging me.
Why cant I have code like this in my .hpp
file.
class H {
private:
static const int i =5;
static const float f = 1.0;
static const string s = "string";
}
Only int, bool, enum and constexpr etc can be declared and initialized like that.
My questions:
Why do strings and other complex datatypes needs proper initialization in cpp? They are constant.
Why do we have different behavior for floats and ints? my guess:gcc does not support that, but can be supported easily if we use constexpr.
It's because the standard says so.
Normally, the out-of-line definition rule applies to static const
members:
The declaration of a
static
data member in its class definition is not a definition.
The only exception is that since C++11 integral and enum static const
types can be initialized in-line.
See [class.static.data]/3 (emphasis mine):
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.
As Bjarne mentioned:
So why do these inconvenient restrictions exist? 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.
The rational could have been that integral types become compile-time constants, although I tend to disagree because the rule of a single address across compilation units still applies, which means the compiler must still emit the static const
members with weak linkage and have the linker fold them, just like it does with multiply defined templates. At which point the restriction on integral types becomes moot since the same folding can be applied to any type. In fact, C++17 "fixes" it with inline
members:
class H {
private:
inline static const int i = 5;
inline static const float f = 1.0;
inline static const string s = "string";
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With