1
votes

I'd like to have a class that has static members to itself, but I can't figure how to do that. Is that even possible?

I get the error:

only static const integral data members can be initialized within a class

Code:

namespace misc
{
    class CData
    {
    public:
        CData( ) { };
        CData( int d );

        CData& operator = ( const CData& d );

        static const CData FIRST = CData( 512 ); //how?

    private:
        int data;
    };
}

As I use FIRST a lot I would like to statically access it using misc::CData::FIRST without the need to declare it somewhere in the scope. Is that by any chance possible?

3
You're using an old compiler, or it's in legacy mode. Try adding --std=c++11 (or --std=gnu++11) to your compiler options.Ben Voigt
Why is your title "static const integral members"? That is quite misleading.juanchopanza
You would like for FIRST to be a static data member because you access it a lot? And why the restriction against declaring (I'm assuming you meant defining) it elsewhere?Praetorian
@juanchopanza: Because that's the error message given by his pre-C++11 compiler.Ben Voigt

3 Answers

3
votes

... without the need to declare it somewhere in the scope. Is that by any chance possible?

No, it's not possible without declaring it (which you already tried to do in your class declaration). You probably meant, without defining it outside your class declaration. Again the answer is no.
You have to separate declaration and definition for this case (it only works with primitive integral types like int to initialize these directly in the class declaration).

First have a simple declaration in your class declaration (usually something like CData.hpp)

namespace misc {
    class CData {
    public:
        CData( ) { };
        CData( int d );

        CData& operator = ( const CData& d );

        static const CData& FIRST;

    private:
        int data;
    };
}

and then define it in a separate compilation unit (usually something like CData.cpp)

namespace misc {
    const CData& CData::FIRST = CData( 512 );
}
0
votes

For non-integral data, something like this is preferred since it avoids the static initialization fiasco.

static const CData FIRST()
{
    static CData first(512); //only initialized once, when first requested

    return first;
}
0
votes

... without the need to declare it somewhere in the scope. Is that by any chance possible?

No.

C++ Standard n3337 § 9.4.2/2

Static data members

The declaration of a static data member in its class definition is not a definition and may be of an incomplete type other than cv-qualified void. The definition for a static data member shall appear in a namespace scope enclosing the member’s class definition. (...)

You can declare a static data member in class:

namespace misc {
    class CData {
    public:
        //...
        static const CData FIRST;  // declaration
        //...
}

and define it in (exactly) one of the .cpp files:

namespace misc {
    CData CData::FIRST = CData( 512 );  // definition
}

This is preferred solution, however you need to have this definition out of your class. You could have defined the member in class if it was of an integral type

C++ Standard n3337 § 9.4.2/3 says

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 (...)