MrDuk
MrDuk

Reputation: 18322

`const int <variable>` cannot appear in a constant-expression

I have the following declarations:

class Rm
{
public:
    //defined message types
    static const int HELLO;
}

in the cpp file I have:

const int Rm::HELLO = 1;

But when I try to use this in a method from another class:

int
Rn::ProcessMessages()
{
    messagesIter iter = messages.begin();
    while(iter != messages.end())
    {
        switch(iter->first)
        {
            case Rm::HELLO:
                myID = iter->second;
                break;  
        }
    }
}

I get this: error: ‘Rm::HELLO’ cannot appear in a constant-expression case Rm::HELLO:

What am I doing wrong?

Upvotes: 0

Views: 1176

Answers (2)

Cheers and hth. - Alf
Cheers and hth. - Alf

Reputation: 145419

In order to use the HELLO value in a switch, it needs to be known by the compiler at this point. Which essentially, for a member constant of integral type, means providing the initializer value in the declaration. Thus, instead of

static const int HELLO;

do

static const int HELLO = -1;

In spite of the initializer this is still just a pure declaration. A separate definition is needed if you take the address of this. Just don't take the address.


The above works for integral types, but even a double member constant can't be defined in this way, for unknown reasons. One alternative then is to use C++11 constexpr, but at this point in time that limits the portability of the code. C++03 alternatives for constants of non-integral types include

  • Use a namespace level constant, not a member.

  • Use a function that produces (a reference to) the value.

  • Define the constant in a class template, derive your class from a specialization.


As a final note, in C++ do reserve all uppercase names such as HELLO for macros. That way you reduce undesired name collisions and text substitutions, and the code gets easier on the eye too. I.e., in C++ use the name hello, or Hello, or...

All uppercase is used in some languages, notably Java and Python, as a convention for names of constants, mainly because in original C constants had to be expressed as macros.

In these languages all uppercase has no ill effect other than being an eyesore, but C++ does have a preprocessor.

Upvotes: 4

Some programmer dude
Some programmer dude

Reputation: 409404

The member variable is a constant, but it's not a compile time constant. For that you need the constexpr keyword that was introduced in C++11:

class Rm
{
public:
    //defined message types
    static constexpr int HELLO = 1;
};

If you don't have a C++11 capable compiler, you can use enumerations instead:

class Rm
{
public:
    //defined message types
    enum
    {
        HELLO = 1
    };
};

Upvotes: 4

Related Questions