Suppose that I want to create a general system which can store variable-width integers together. In this system, we can use an enum, which contain member names (this enum members have consecutive values [0;count)):
enum class Group1 {
AttrA,
AttrB,
AttrC,
};
I add inline constexpr specialization, which tells, how many members are there:
template <typename TYPE>
inline constexpr int count = -1;
template <>
inline constexpr int count<Group1> = 3; // Group1 has 3 members (AttrA/B/C)
And I add inline constexpr specializations which describes each members width:
template <auto VALUE>
inline constexpr int nBits = -1;
template <>
inline constexpr int nBits<Group1::AttrA> = 3; // AttrA need 3 bits of storage
template <>
inline constexpr int nBits<Group1::AttrB> = 2;
template <>
inline constexpr int nBits<Group1::AttrC> = 4;
Now, I'd like to have a general constexpr function , which can calculate summed width (of any type, not just Group1):
template <typename TYPE>
constexpr int summedWidth() {
int r = 0;
for (int i=0; i<count<TYPE>; i++) {
r += nBits<static_cast<TYPE>(i)>;
}
return r;
}
However, this doesn't compile, because of the r += nBits... line:
error: non-type template argument is not a constant expression
Is it possible to create a compilable summedWidth() function (or any other solution, which provides a compile-time constant)?