16

I have two structures a and b:

struct a {
    static constexpr int f() {
        return 1;
    }

    static constexpr int c = f();
};

template<int I>
struct b {
    static constexpr int f() {
        return I;
    }

    static constexpr int c = f();
};

a is obviously not working because f is considered to be not defined here. But why the hell b is valid?

JorgeAmVF
  • 1,660
  • 3
  • 21
  • 32
Antoine Morrier
  • 3,930
  • 16
  • 37
  • Why is `a::f` considered incomplete? – Nicol Bolas Mar 16 '18 at 21:48
  • 4
    @NicolBolas Not incomplete but not defined, see: https://stackoverflow.com/questions/16493652/constexpr-not-working-if-the-function-is-declared-inside-class-scope – NathanOliver Mar 16 '18 at 21:49
  • 2
    This is interesting. I think the answer has to with the fact that template members are all first defined and only later instantiated. But finding relevant Standard quotes is proving tricky, and the whole thing brings up other questions... – aschepler Mar 16 '18 at 21:57
  • 2
    This is another variant of core issue 2335. – T.C. Mar 17 '18 at 01:23
  • can adding inline help in c++17 ? – code707 May 19 '18 at 18:05

1 Answers1

1

I'm not sure about that but i think that the compiler will expand that template in this way (in the case that int I would be 1):

struct b {
    static constexpr int f();
    static const int c;
};

constexpr int b::f(){
    return 1;
};

const int b::c = f();

So it compiles because the call of b::f is done after its declaration

infact if you declare a in this way it will compile:

struct a {
    static constexpr int f();
    static const int c;
};

constexpr int a::f(){
    return 1;
};

const int a::c = f();

So the answer is that during compiling the compiler evaluates b::c as a const value and not constexpr.

P.Carlino
  • 661
  • 5
  • 21