可能是愚蠢的问题:我正在尝试执行以下操作
template<unsigned int N>
class Foo{...}; // Define class Foo accordingly
int main(){
for (unsigned int i = 0; i < 10; i++){
Foo<i> f(3);
f.show();
}
return 0;
}
正如你所想象的,它不会编译,因为变量 i
不是const
。我知道这样做的原因是在非类型模板参数 Foo<i>
内分配的值必须在编译时知道,因为这里不是这种情况,所以它并不真正知道该怎么做。现在我想知道是否有办法解决这个问题。第一个想法当然是声明 unsigned int N
作为 Foo 类的成员变量。
所以问题:是否可以使用模板参数实现上述所需的行为,或者我是否必须声明 unsigned int N
作为我的类的成员变量?
P.S.:我试图找到一个相关的问题,但我发现的问题与如何使用非类型模板参数有关,他们没有完全回答问题。由于他们没有提到这是可能的,我认为这是不可能完成的......
编辑。
是否可以执行以下操作?
template<unsigned int N>
class Foo{...}; // Define class Foo accordingly
int main(){
std::vector<Foo> v; // I know it's better with shared_ptr, etc.. but to get the idea..
for (unsigned int i = 0; i < 10; i++){
Foo<i> f(3);
f.show();
v.push_back( f );
}
return 0;
}
最佳答案
我们没有for constexpr
在语言中,所以你不能直接这样做。你必须以某种方式模拟编译时 for
环形。有多种选择。
使用
std::integer_sequence
(C++14) 和int...
包:template<int i> void foo() { Foo<i> f(3); f.show(); } template<int... is> void foo(std::integer_sequence<int, is...>) { (foo<is>(), ...); // expands into foo<0>(), foo<1>(), ..., foo<9>() } foo(std::make_integer_sequence<unsigned int, 10>{});
使用递归和
if constexpr
(C++17) 模拟for
循环:template<unsigned int i> void foo() { Foo<i> f(3); f.show(); if constexpr (i + 1 < 10) foo<i + 1>(); } foo<0>();
使用
std::integral_constant
(C++11) 和函数重载:void foo(std::integral_constant<unsigned int, 10>) {} template<unsigned int i> void foo(std::integral_constant<unsigned int, i>) { Foo<i> f(3); f.show(); foo(std::integral_constant<unsigned int, i + 1>{}); } foo(std::integral_constant<unsigned int, 0>{});
Foo<i>
和Foo<j>
是不同的 i
的不同类型和j
。您不能将不同的类型放入 std::vector
中。如果i
s 在编译时已知,您可以创建 std::tuple
的Foo<i>
s。但这仍然需要使用一些模板技巧。
关于c++ - 为模板传递非类型参数参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59370557/