初始化列表是否足够静态以允许实例化模板?

Vic*_*out 2 c++ templates compile-time-constant c++11 stdinitializerlist

我为这个错误的问题道歉。我不知道该怎么问。

#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;
}
Run Code Online (Sandbox Code Playgroud)

我认为有限次数的迭代足以使该模板化函数实例化,但事实并非如此。

有没有办法让它发挥作用?

Tre*_*ntP 6

不,你不能那样做。然而,问题不在于std::initializer_list不够恒定。它不起作用,因为您不能output<>()在循环的每次迭代中更改类型。

初始值设定项列表可以是constexpr,并且constexpr值可以用作非类型模板参数。例如,这些都有效:

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

在您的代码中,v不是constexpr. 它在循环的每次迭代中都会发生变化。所以它不能用作非类型模板参数。

总而言之, an std::initialier_list<>,这样一个列表的大小,以及列表的一个特定元素,都是足够恒定的非类型模板参数。对列表中元素的引用(在循环的每次迭代中都会发生变化)不够恒定。

您会发现在循环的每次迭代中发生的变化都不够恒定。以同样的方式,auto用于在迭代之间更改类型的循环中的变量也是不可能的。

整数常量表达式和类型只能在模板化对象或函数的实例化之间更改。在模板的每次实例化时,它们都有一个针对正在实例化的对象/函数的整个范围固定的值。它们不能在循环的迭代之间改变。


Igo*_*nik 5

沿着这些路线的东西,也许:

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

output_many<1, 2, 3>();
Run Code Online (Sandbox Code Playgroud)

演示