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,
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.