Question

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.

Était-ce utile?

La solution 2

There's an exception to that rule for const static members that:

  1. Are of integer or enumeration type (pointers, references, floats need not apply)
  2. Never have their address taken or get bound to a reference

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.

Autres conseils

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

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.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top