1

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?

7
  • 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
    Commented May 20, 2014 at 18:26
  • stackoverflow.com/questions/6106194/…
    – merlin2011
    Commented May 20, 2014 at 18:27
  • 3
    Why is your title "static const integral members"? That is quite misleading. Commented May 20, 2014 at 18:31
  • 1
    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
    Commented May 20, 2014 at 18:39
  • 1
    @juanchopanza: Because that's the error message given by his pre-C++11 compiler.
    – Ben Voigt
    Commented May 20, 2014 at 18:43

3 Answers 3

3

... 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 );
}
7
  • "...without the need to decleare it somewhere in the scope..."
    – 4pie0
    Commented May 20, 2014 at 18:34
  • 2
    @privatedatapublicchannel2 "...without the need to decleare it somewhere in the scope..." That's as irrelevant as asking for fairies or unicorns ... Commented May 20, 2014 at 18:36
  • irrelevant are assumptions, but "without the need to decleare it somewhere in the scope" is a wish of the OP, it is part of the question
    – 4pie0
    Commented May 20, 2014 at 18:40
  • 1
    @privatedatapublicchannel2 Then the OP should clarify this point, don't you think so? There's often people wish to have this or that from c++, that the language simply doesn't support. Commented May 20, 2014 at 18:41
  • I meant "global scope". I find it nicer having it inside the class "Data::FIRST" so you know what it belongs to rather than "extern DATA bla.." which is in my opinion kinda messy if you have a lot of data. Thanks for the post, this works perfect +1 Commented May 20, 2014 at 18:51
1

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

14
  • 2
    I didn't downvote, but I don't think the question is really related to the singleton pattern here :-/ ... Commented May 20, 2014 at 18:32
  • 1
    So the most straightforward way to solve the OP's problem is to create a singleton?
    – Praetorian
    Commented May 20, 2014 at 18:34
  • 1
    Well, the OP also seems to think he needs the static data member because he accesses it a lot. The answer to the original problem is to provide a definition for the static member, not create a singleton. Anyway, didn't downvote, so can't help you with that.
    – Praetorian
    Commented May 20, 2014 at 18:42
  • 1
    @πάνταῥεῖ now it does provide additional info
    – 4pie0
    Commented May 20, 2014 at 20:42
  • 1
    @privatedatapublicchannel2 you've come a long way baby Commented May 20, 2014 at 20:47
0

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;
}

Not the answer you're looking for? Browse other questions tagged or ask your own question.