c++ - 为模板参数的所有组合实例化函数,在运行时选择实例化

标签 c++ templates

很抱歉,如果之前有人问过这个问题,但我找不到这个确切的问题。

我有一个看起来像这样的模板化 CUDA 内核:

template<int firstTextureIndex, int secondTextureIndex, int thirdTextureIndex> __global__ void myKernel

三种纹理索引模板类型的范围为 0-7,直到运行时才知道。我需要实例化这个内核的所有 512 种组合,然后根据纹理索引的运行时值调用正确的模板。

我从来没有写过任何预处理宏,并且正在努力避免它。另一个帖子,here , 展示了如何通过这样做递归地为一个模板变量实例化多个 class 模板:

template<int i>
class loop {
    loop<i-1> x;
}

template<>
class loop<1> {
}

loop<10> l;

我正在努力将它扩展到 3 个变量和一个函数(而不是一个类)以适应我的情况。即使我弄清楚如何以这种方式实例化所有这些,我如何在没有嵌套 switch 语句的情况下在运行时实际调用 512 种可能性中的 1 种?为了说明这一点,我试图避免的嵌套 switch 语句如下:

switch(firstTextureIndex)
{
    case 0:
        switch(secondTextureIndex)
        {
            case 1:
                switch(thirdTextureIndex)
                {
                    case 2:
                        myKernel<0, 1, 2><<<grid, block>>>(param1, param2, param3);
                        break;
                }
             break;
        }
    break;
}

如果我弄清楚如何为它们全部实例化 0-7,我可以这样调用它吗:

myKernel<i, j, k><<<grid, block>>>(param1, param2); 

如果我让 i、j 和 k 枚举类型只包含 0-7?这样编译器就可以知道所有可能的值,并且由于我将它们全部实例化,所以它可以吗?

请注意,这个三重模板有充分的理由传递纹理索引,但为了简洁起见,我省略了解释。非常感谢任何有关实例化和/或调用此内核的帮助。

编辑:Jarod42 提供了一个有效的解决方案,完全符合我的要求。不幸的是,我现在意识到 c++ 标准在这里很重要。我正在使用 c++98/03 结合最新稳定版本的 boost 库,因此使用这些的解决方案将是理想的。我可能会使用 c++11,但由于我们的编译器的限制,c++14 已经过时了。

最佳答案

你可以这样做:

template <std::size_t I>
void do_job()
{
    myKernel<I / 64, (I / 8) % 8, I % 8>{}();
}

template <std::size_t ... Is>
void callMyKernel(std::index_sequence<Is...>, std::size_t i, std::size_t j, std::size_t k)
{
    std::function<void()> fs[] = {&do_job<Is>...};

    fs[i * 64 + j * 8 + k]();
}

void callMyKernel(std::size_t i, std::size_t j, std::size_t k)
{
    callMyKernel(std::make_index_sequence<512>{}, i, j, k);
}

Demo

关于c++ - 为模板参数的所有组合实例化函数,在运行时选择实例化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35562342/

相关文章:

php - C++代码的Web前端

python - 在 Pyramid 中创建动态类 View

c++ - Variadic template 选择更通用的模板而不是重载

c++ - 如何获取 Windows 控制台高度?

c++ - Qt 拖放与自己的小部件?

c++ - 名称后跟 '::' 必须是类或命名空间错误,即使 '::' 跟在类名之后

c++ - 本身就是模板的特化

c++ - 在模板层次结构中继承类型声明

c++ - R:指向c函数的指针

iphone - iphone 应用程序中的 C++ 对象