The problem that we have here is indirectly described in 3.3.7 - Class scope:
typedef int c;
enum { i = 1 };
class X {
char v[i]; // error: i refers to ::i
// but when reevaluated is X::i
int f() { return sizeof(c); } // OK: X::c
char c;
enum { i = 2 };
};
This paragraph should describe this a little bit more (9.2.2):
A class is considered a completely-defined object type (3.9) (or complete type) at the closing } of the class-specifier.Within the class member-specification, the class is regarded as complete within function bodies, default arguments, exception-specifications, and brace-or-equal-initializers for non-static data members (including such things in nested classes). Otherwise it is regarded as incomplete within its own class member-specification.
As std::array<Class2, Class1::GetCount()> is neither of the functions bodies, default arguments, exception-specification, brace-or-equal initializers, at that point, class is considered incomplete, so I think it's up to the compiler to decide whenever it will allow this, or not - but not compiling the code is OK by the standard.
Only solutions that I can think of is the one you suggested, or moving constexprs into another (possible base) class.
GetCount()used before its definition". Presumably, this is becauseClass1is incomplete in its member declarations. But that's not an answer because (a) I'm not sure, and (b) I don't know how to fix it.Class1works. But I would like to see how this can be fixed.