1

I have a class defined within a function. An object of that class type is instantiated later in the function, and I want to define a constant inside that class, which is referred to from the function.

Live code

void foo() {
    class Internal {
    public:
        // here is the constant !!!
        static constexpr int NONE = std::numeric_limits<int>::max();
        // ------------------------
        Internal(int n = NONE) : _n(n) {}
        int get() const { return _n; }
    private:
        int _n;
    };
    
    Internal x(123), y;
    
    if (x.get() == Internal::NONE) {
       std::cout << "x" << std::endl; // not printed
    }
    if (y.get() == Internal::NONE) {
       std::cout << "y" << std::endl; // printed
    }
}

This yields a compile error:

error: local class 'class foo()::Internal' shall not have static data member 'constexpr const int foo()::Internal::NONE' [-fpermissive]

Removing the static, leaving just constexpr, results in:

error: non-static data member 'NONE' declared 'constexpr'

Just using const results in:

error: invalid use of non-static data member 'foo()::Internal::NONE'

FWIW, static const doesn't work either.

Is there any way to accomplish this aside from moving the constant out of the class scope?

tomocafe
  • 1,425
  • 4
  • 20
  • 35
  • 1
    Anticipating a follow-up question, given the answer that it cannot be done: [Why not?](https://stackoverflow.com/questions/8162994/why-arent-static-data-members-allowed-in-local-classes) – JaMiT Mar 06 '21 at 02:37

3 Answers3

3

According to https://www.ibm.com/support/knowledgecenter/ssw_ibm_i_74/rzarg/cplr062.htm

A local class cannot have static data members. In the following example, an attempt to define a static member of a local class causes an error:

and https://en.cppreference.com/w/cpp/language/class under heading Local classes

A local class cannot have static data members

So "Is there any way to accomplish this aside from moving the constant out of the class scope?"

  • No.
Captain Giraffe
  • 14,407
  • 6
  • 39
  • 67
1

No, static constexpr members are banned from local classes. Probably because it wasn't free for compilers to implement it, unlike local classes. (Where is its storage declared? When is it initialized? Etc. All could be answered, but getting those answers right is a cost).

 static constexpr int NONE(){ return std::numeric_limits<int>::max(); }

this, however, works.

JaMiT
  • 14,422
  • 4
  • 15
  • 31
Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524
  • Accepted this one (even though the others are technically correct) because it follows the spirit of what I was going for by slightly adjusting the question. Instead of using a constant, I can use a `static constexpr` method. Thanks! – tomocafe Mar 06 '21 at 09:52
0

Is there any way to accomplish this aside from moving the constant out of the class scope?

Sure. Another way to accomplish this is to move the class out of the block scope.

eerorika
  • 232,697
  • 12
  • 197
  • 326