2

I cannot understand why static constexpr behaves differently then global constexpr. What am I doing wrong? Compiler error is not particularly helpful:

prog.cpp:20:17: error: ‘static constexpr int Bar::foo(const char*)’ called in a constant expression
B = Bar::foo(s)
             ^
prog.cpp:20:17: error: enumerator value for ‘B’ is not an integer constant

code is as follows:

#include <iostream>

constexpr int foo(const char* v)
{
    return v[0];
}

struct Bar
{
    static constexpr int foo(const char* v)
    {
        return v[0];
    }

    static constexpr const char* s = "abc";

    enum
    {
        A = ::foo(s),
        B = Bar::foo(s)
    };
};

int main()
{
    int a[Bar::A];
    a[0] = Bar::A;
}
Jarod42
  • 203,559
  • 14
  • 181
  • 302
kpx1894
  • 381
  • 2
  • 8

1 Answers1

4

This is because the enum is part of the class declaration, whereas the definitions of the functions inside the class are logically deferred until after the class declaration. This means that as far as the enum is concerned, it can't see the definition of B::foo, and therefore it can't use a call to it as a constant expression. You can see this by putting the enum after the class:

#include <iostream>

constexpr int foo(const char* v)
{
    return v[0];
}

struct Bar
{
    static constexpr int foo(const char* v)
    {
        return v[0];
    }

    static constexpr const char* s = "abc";
};

enum Enum
{
    A = ::foo(Bar::s),
    B = Bar::foo(Bar::s)
};

which gives no error.

Vaughn Cato
  • 63,448
  • 5
  • 82
  • 132
  • Unfortunately, this causes the enum to not be part of the class. [But you can still do that.](http://coliru.stacked-crooked.com/a/838e6daf5c9186c9) – chris Aug 07 '14 at 14:07
  • What about initialisation of static constants? My intuition tells me they are done quite late. Compiler error is different: "field initializer is not constant". – kpx1894 Aug 07 '14 at 14:42