I was looking up ways to initialize static map in C++ and found this code:
struct A{
static map<int,int> create_map()
{
map<int,int> m;
m[1] = 2;
m[3] = 4;
m[5] = 6;
return m;
}
static const map<int,int> myMap;
};
const map<int,int> A:: myMap = A::create_map();
However, if I change the last line to
const static map<int,int> A:: myMap = A::create_map();
Compiler complaints: 'static' may not be used when defining (as opposed to declaring) a static data member" ?
I wonder why? What's the logic or reasoning behind this ?
Classes can contain static member data and member functions. When a data member is declared as static , only one copy of the data is maintained for all objects of the class. In the preceding code, the member bytecount is declared in class BufferedOutput , but it must be defined outside the class declaration.
The reason is that a class might be declared (through #include) in many Translation Units, if it was defined on all of them there would be a repeated symbol. static class members have external linkage, and must comply to the restrictions placed on that model, one definition only.
Once you define a static data member, it exists even though no objects of the static data member's class exist. In the above example, no objects of class X exist even though the static data member X::i has been defined. Static data members of a class in namespace scope have external linkage.
Static data members are initialized when they are defined, outside of any member function, exactly like the initialization of ordinary (non-class) global variables.
static int a = 0; // grandfathered and still useful, provides static *LINKAGE*
// and static STORAGE DURATION
static int X::a = 0; // confusing and illegal, is it static LINKAGE
// or static STORAGE DURATION
// or static MEMBERSHIP?
static
already had a meaning (in C) when used on a variable definition. It would be very surprising for C programmers learning C++ to find that meaning was changed sometimes, but not always.
So the new meaning (static membership) is only active inside the class definition (where C didn't allow the static
keyword).
Declaring a class member static
means it is shared between all objects of this class.
When you add static
to a variable definition outside of a class, it means this variable has file scope and is not visible outside this file.
If it would be allowed to
const static map<int,int> A:: myMap = A::create_map();
this would mean, you have a static member variable, which is not visible outside of this file. This just doesn't make sense.
It's no different than
struct A
{
static int x;
}
int A::x; //legal
static int A::x; //illegal
Everything else is just more keywords thrown at this minimal, conceptually identical, example. A static
member can only be declared static
inside the class definition.
The
const map<int,int> A:: myMap = A::create_map();
outside the class is just a definition of the static
member A::myMap
. The extra static
makes no sense there.
The reasoning behind this is probably to avoid confusion - a static
free variable is kind of a "private" variable (to a translation unit). A member static
is the opposite.
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