Search code examples
c++templatescompiler-errorscompiler-bug

Accessing a static constexpr member from a member variable, GCC bug?


The following compiles without error:

template<int j, int i>
struct TemplateClass { 
    int arr[i];
};
struct A {
    inline static constexpr int n = 123; 
};
template<int j> struct B {
    void func() {
        A a;
        TemplateClass<j, a.n> c;
    }
};
int main() {
  B<456> b;
  b.func();
}

However, compiling with GCC, we get the error "use of 'this' in a constant expression" if we make a member variable of the variable A a in the function func, like this:

template<int j> struct B {
    A a;
    void func() {
        TemplateClass<j, a.n> c;
    }
};

Compiling with MSVC gives no error. Compare the two compilers,

  • I do not understand why this gives an error. Is this a bug?
  • Is there a workaround to circumvent this error?

Solution

  • GCC is correct. A template argument must be a constant expression, and a.n implicitly means this->a.n since a is a member of the enclosing class. But a constant expression evaluation cannot access this inside a non-constexpr member function ([expr.const]/2.1). And even though evaluating this appears unnecessary in order to obtain the value of the static member n, the standard requires that a (which means this->a) be evaluated even though its value is not needed; see [expr.ref]/1 and its footnote.

    GCC will accept your code if func is marked constexpr. As pointed out in the comments, it's better to just write A::n, though.