Given a template whose non-type parameter determines the size of a non-const int
array member, how can I access the array elements by an integral index at compile time? I want the access to be done via the class template’s getter method at
.
I figured since class templates must be instantiated before runtime, I can pass another non-type class template’s enum
member value to the prior class’s at
method to ensure the index
argument is a compile-time constant.
I left the class template deliberate_error
undefined to see if its arguments are computed at compile time and to view the compile-time results in the error messages.
template <unsigned int N>
struct compile_time_int {
enum {num = N};
};
template <unsigned int N>
struct array_wrapper {
int arr[N];
template <unsigned int Ind>
constexpr int const& at(compile_time_int<Ind> const& index) const {
return arr[index.num];
}
};
template <unsigned int> struct deliberate_error;
int main() {
compile_time_int<2> cti;
array_wrapper<3> aw;
aw.at(cti);
deliberate_error<cti.num> my_error1;
deliberate_error<aw.at(cti)> my_error2;
}
aw.at(cti);
doesn’t give an error, so I thought that if I passed the same expression to deliberate_error
instance my_error2
, the compiler will display the value of arr[2]
in the error message.
my_error1
causes g++ error: aggregate 'deliberate_error<2u> my_error1' has incomplete type and cannot be defined
,
showing cti
’s wrapped integral value 2
. So, I thought if I passed the same cti
to object aw
's getter, and then pass the result to my_error2
, I can get arr[2]
in the error message. But instead, it prints:
error: the value of 'aw' is not usable in a constant expression
note: 'aw' was not declared 'constexpr'
note: in template argument for type 'unsigned int'
error: invalid type in declaration before ';'
So, I tried prepending constexpr
to aw
’s declaration, but that gives even more undesirable errors. What’s wrong here, and how can I fix it?