constexpr with std::array - "Non-type template argument is not a constant expression"
Following Nemanja Boric's answer, I converted the static methods into static members. This isn't the fix I wanted, but it works. I suppose the remaining question is why didn't it work?
#include <array>
#include <cstdint>
class Class2
{
};
class Class1
{
public:
static constexpr uint8_t Max = 5;
static constexpr uint8_t Min = 0;
static constexpr uint8_t Count = Max - Min + 1;
private:
std::array<Class2, Class1::Count> m_classes;
};
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.