lambda 函数使用它的参数作为模板参数调用模板函数

lambda function uses its parameter as template parameter calling template function

以下是示例代码,无法编译。

我们使用 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;
    });
}

您不能使用 运行-time 变量作为模板参数,它应该是一个编译时常量。但是你可以将常量包装成 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类型的wrapped值。

Demo