以下是无法编译的示例代码。
我们使用 iteration 函数在一定范围内进行迭代,并运行lambda回调函数。 iterate 函数会将一些指示(即 type )传递给回调lambda函数,然后该函数将根据指示进行工作。由于这些指示在编译时是固定的,因此我相信有一种方法可以消除运行时的所有指示开销。但是如何..?
template<typename FuncT>
void iterate(const FuncT& func) {
for(int i = 0; i < 5; ++i)
func(0, i);
for(int i = 0; i < 5; ++i)
func(1, i);
}
template<int d> int getValue(int i) { return d+i; }
// this has run-time overhead compared to the template version
// int getValue(int d, int i) {return d+i; }
int main() {
iterate([&](const int type, int index){
// error: cannot compiler here
// candidate template ignored: invalid explicitly-specified argument for template parameter 'd'
std::cout<<getValue<type>(index)<<std::endl;
});
}
答案 0 :(得分:1)
不能将运行时变量用作模板参数,该参数应该是编译时常量。但是您可以将常量包装到std::integral_constant
中,以将常量值编码为类型:
template<typename Func>
void iterate(Func func) {
for(int i = 0; i < 5; ++i)
func(std::integral_constant<int, 0>{}, i);
for(int i = 0; i < 5; ++i)
func(std::integral_constant<int, 1>{}, i);
}
template<int d>
int getValue(int i) {
return d + i;
}
int main() {
iterate([&](auto type, int index) {
std::cout << getValue<type>(index) << std::endl;
});
}
std::integral_constant
可以隐式转换为基础类型的值。在getValue<type>(index)
中,type
转换为类型为int
的包装值。