Reputation: 972
In C++ Primer 4th 12.6.2, It recommend to redeclare a const static variable outside a class.
However, The code below passed in gcc 4.6.3.
#include <iostream>
using namespace std;
class X {
public:
const static int a = 1;
};
// const int X::a;
int main() {
X x;
cout << x.a << endl;
return 0;
}
Should we redeclare it?
PS:
As recommended by Potatoswatter I added a function to use const static member as a reference:
const int X::a;
void test(const int& a) {
cout << a << endl;
}
int main() {
X x;
test(X::a);
return 0;
}
If we do not include const int X::a
outside class X
, it produced error as below
undefined reference to 'X::a'
It is a good practise to make a definition outside a class whether const static or not.
Upvotes: 4
Views: 3039
Reputation: 137770
There's an exception to that rule for const static
members that:
For static constexpr
members, the type restriction is dropped (or, replaced with those of constexpr
), and there must be an initializer at the in-class declaration.
In either case, the declaration is not considered to be a definition, despite having an initializer, so the object doesn't get an address until it's declared (hence defined) outside the class. For members of a template, that may be done in every translation unit (TU), for members of a non-template class it must be done in only one TU.
Although your example does compile, the practice isn't generally scalable because such variables can't be passed to generic pass-by-reference functions, including perfect forwarding. The book's advice is good.
Standard reference: [class.static.data] §9.4.2/3.
Upvotes: 2
Reputation: 50657
No, you don't need to re-declare it as you have already declared and defined it in the single line:
const static int a = 1;
However, for static
data members (including const static
), if you only give its declaration in the class. You must define the static member outside of the class declaration, in namespace scope. For example:
class X
{
public:
static int i; // declaration
};
int X::i = 0; // definition outside class declaration
Upvotes: 3
Reputation: 206567
From http://en.cppreference.com/w/cpp/language/static:
Constant static members
If a static data member of integral or enumeration type is declared const (and not volatile), it can be initialized with a brace-or-equal initializer that is a constant expression, right inside the class definition. In this case, no definition is needed:
The compiler is behaving as expected. It's hard to judge the recommendation of "The C++ Primer" without adequate context.
Upvotes: 2