Is an initializer list static enough to allow instantiating templates?

97 Views Asked by At

I apologize for the badly formed question. I wasn't sure how to ask it.

#include <iostream>

template <int V>
void output() {
  std::cout << V << "\n";
}

int main() {

  output<1>(); // this works
  output<2>();

  for (int v : {1,2,3} ) {
    output<v>(); // this not
  }
  return 0;
}

I thought having a finite number of iterations would be enough to make that templated function instantiated, but no.

Is there a way to get this to work?

2

There are 2 best solutions below

1
On

Something along these lines, perhaps:

template <int ... Vs>
void output_many() {
    (output<Vs>(),...);
}

output_many<1, 2, 3>();

Demo

0
On

No, you can't do that. However, the problem isn't that std::initializer_list isn't constant enough. It doesn't work because you can't have output<>() change types on each iteration of the loop.

An initializer list can be constexpr, and a constexpr value can be used as a non-type template parameter. For example, these all work:

constexpr std::initializer_list<int> x{10, 20};
output<x.size()>();
output<*x.begin()>();
constexpr const int& ref = *x.begin();
output<ref>();

In your code, v is not constexpr. It changes on each iteration of the loop. So it can't be used as a non-type template parameter.

To summarize, an std::initialier_list<>, the size of a such a list, and a specific element of the list, are all constant enough to be non-type template parameters. A reference to elements in the list, which changes on each iteration of a loop, is not constant enough.

You will find that nothing which changes on each iteration of a loop is constant enough. In the same manner, an auto variable in loop that is intended to change types between iterations is also not possible.

Integer constant expressions and types can only change between instantiations of a templated object or function. On each instantiation of the template they have a value fixed for the entire scope of the object/function being instantiated. They can not change between iterations of a loop.