Use a non-const variable as an index into a constexpr array to pass to a template parameter


oak duck

I have an constexpr size_tarray whose members will be passed to the template parameter of an initialized class, iterating through the array to construct and use several different templated objects. Here's the general idea:

template <size_t N>
class Foo
{
    // magic
};

constexpr size_t c_arr[] = { 2, 5, 3, 2 };

for (int i = 0; i < 4; i++)
{
    Foo<c_arr[i]> foo;
    foo.bar();
}

However, this throws the following error:

templ_arr.cpp: In function ‘int main()’:
templ_arr.cpp:56:21: error: the value of ‘i’ is not usable in a constant expression
         Foo<c_arr[i]> foo;
                     ^
templ_arr.cpp:51:14: note: ‘int i’ is not const
     for (int i = 0; i < 3; i++)
              ^
templ_arr.cpp:56:20: note: in template argument for type ‘long unsigned int’
         Foo<c_arr[i]> foo;

I can't seem to find a way to use const_caston ito allow it to be used within a parameter, nor can I fix it by doing something like this as it gives me the same error:

for (int i = 0; i < 4; i++)
{
    const int j = i;
    Foo<c_arr[j]> f;
    foo.bar();
}

What am I doing wrong and how can I fix this?

Jin Sunda

If you want to use the value as a template parameter, use std::integer_sequence

template <size_t N>
class Foo
{
 public:
  void bar() {}
};

template<std::size_t ...I>
void foo_bar(std::index_sequence<I...>) {
  int dummy[] = { (Foo<I>{}.bar(), 0) ... };
  // ((Foo<I>{}.bar()), ...); if using C++17 or above
}

int main() {
  constexpr std::index_sequence<2, 5, 3, 2> id;

  foo_bar(id);
}

Related


MSVC error with constexpr array as template non-type parameter

Tenniston I'm trying to understand if what I'm seeing is an MSVC compiler bug or my misunderstanding. I'm trying to use a simple compile-time string literal template parameter like this: constexpr const char teststr[] = "teststr"; template <const char *N> str

MSVC error with constexpr array as template non-type parameter

Tenniston I'm trying to understand if what I'm seeing is an MSVC compiler bug or my misunderstanding. I'm trying to use a simple compile-time string literal template parameter like this: constexpr const char teststr[] = "teststr"; template <const char *N> str

MSVC error with constexpr array as template non-type parameter

Tenniston I'm trying to understand if what I'm seeing is an MSVC compiler bug or my misunderstanding. I'm trying to use a simple compile-time string literal template parameter like this: constexpr const char teststr[] = "teststr"; template <const char *N> str

How to pass constexpr as template parameter?

Peter Bell I have a templated class MyClassthat I want to run against various parameters to measure some values. I know the exact parameters before compiling, so I figured there must be a way to achieve my goal. My code so far: template <int T> class MyClass {

How to pass constexpr as template parameter?

Peter Bell I have a templated class MyClassthat I want to run against various parameters to measure some values. I know the exact parameters before compiling, so I figured there must be a way to achieve my goal. My code so far: template <int T> class MyClass {

How to pass constexpr as template parameter?

Peter Bell I have a templated class MyClassthat I want to run against various parameters to measure some values. I know the exact parameters before compiling, so I figured there must be a way to achieve my goal. My code so far: template <int T> class MyClass {

How to pass constexpr as template parameter?

Peter Bell I have a templated class MyClassthat I want to run against various parameters to measure some values. I know the exact parameters before compiling, so I figured there must be a way to achieve my goal. My code so far: template <int T> class MyClass {

How to pass constexpr as template parameter?

Peter Bell I have a templated class MyClassthat I want to run against various parameters to measure some values. I know the exact parameters before compiling, so I figured there must be a way to achieve my goal. My code so far: template <int T> class MyClass {

Template const/non-const parameter conversion

Burt Brill I went through some searching but couldn't find it. Consider this situation: template <class T> class TemplClass; void a_function(TemplClass<const X>&); TemplClass<X> inst; a_function( inst ); // fails "Invalid initialization of reference of type

Template const/non-const parameter conversion

Burt Brill I went through some searching but couldn't find it. Consider this situation: template <class T> class TemplClass; void a_function(TemplClass<const X>&); TemplClass<X> inst; a_function( inst ); // fails "Invalid initialization of reference of type

Template const/non-const parameter conversion

Burt Brill I went through some searching but couldn't find it. Consider this situation: template <class T> class TemplClass; void a_function(TemplClass<const X>&); TemplClass<X> inst; a_function( inst ); // fails "Invalid initialization of reference of type

Pass the index of the array to the template

mgrenier: How can I pass the index of the array to the template? I know I can do something like this to access the first element: {{ with index . 0 }} But I need to do something like this: {{ template "mytemp" index . 0 }} This doesn't seem to work. I also t

Pass the index of the array to the template

mgrenier: How can I pass the index of the array to the template? I know I can do something like this to access the first element: {{ with index . 0 }} But I need to do something like this: {{ template "mytemp" index . 0 }} This doesn't seem to work. I also t

Using constexpr array as template non-type parameter (C++14)

Vladimir Reshenikov #include <iostream> using namespace std; template<const int arr[]> struct S { static constexpr int value = arr[0]; }; constexpr int arr[] = { 5 }; int main() { cout << S<arr>::value << endl; } The program compiles fine and prin

Using constexpr array as template non-type parameter (C++14)

Vladimir Reshenikov #include <iostream> using namespace std; template<const int arr[]> struct S { static constexpr int value = arr[0]; }; constexpr int arr[] = { 5 }; int main() { cout << S<arr>::value << endl; } The program compiles fine and prin