本文介绍了C++ 模板实例化:避免长切换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个依赖于整数模板参数的类.在我的程序中,我想使用此模板的一个实例,具体取决于运行时确定的此参数的值.这是一个简单的例子,演示了我目前将如何使用一个大的 switch 语句:

I have a class depending on an integer template parameter. At one point in my program I want to use one instantiation of this template, depending on a value of this parameter determined at runtime. Here is a simple example demonstrating how I would go about this currently, using a big switch statement:

#include <string>
#include <iostream>
#include <type_traits>

template<unsigned A>
struct Wrapper {
    typedef typename std::conditional<A==1, int, float>::type DataType;
    DataType content[A];
    void foo() {
        std::cout << A << std::endl;
    };
};

int main(int argc, char *argv[])
{
    std::string arg = argv[1];
    int arg_int = std::stoi(arg);

    switch (arg_int) {
    case 1: {
        Wrapper<1> w;
        w.foo();
        break;
    }
    case 2: {
        Wrapper<2> w;
        w.foo();
        break;
    }
    case 3: {
        Wrapper<3> w;
        w.foo();
        break;
    }
    default:
        return 1;
    };

    return 0;
}

一旦我不仅有一个参数 A,而且有多个不同组合的模板参数,这将很快变得笨拙.我们还假设,实际上有一个很好的理由将 A 实现为模板参数.

This will quickly get unwieldy once I have not only one parameter A, but multiple template arguments in various combinations. Let's also assume that in reality there is a really good reason to implement A as a template parameter.

有没有办法用几乎相同的 case 语句替换巨大的 switch 语句,例如使用来自 Boost 的一些元编程魔法还是预处理器黑客?

Is there a way to replace the huge switch statement with almost identical case statements, e.g. using some metaprogramming magic from Boost or a preprocessor hack?

理想情况下,我希望能够编写如下内容:

Ideally I would like to be able write something like the following:

INSTANTIATE_DEPENDING(i, {1, 2, 3},
            {
                Wrapper<i> w;
                w.foo();
            }
    );

推荐答案

你可以使用可变参数模板,可能像这样:

You could use a variadic template, maybe like this:

#include <cstdlib>
#include <string>

int main(int argc, char * argv[])
{
    if (argc != 2) { return EXIT_FAILURE; }

    handle_cases<1, 3, 4, 9, 11>(std::stoi(argv[1]));
}

实施:

template <int ...> struct IntList {};

void handle_cases(int, IntList<>) { /* "default case" */ }

template <int I, int ...N> void handle_cases(int i, IntList<I, N...>)
{
    if (I != i) { return handle_cases(i, IntList<N...>()); }

    Wrapper<I> w;
    w.foo();
}

template <int ...N> void handle_cases(int i)
{
    handle_cases(i, IntList<N...>());
}

这篇关于C++ 模板实例化:避免长切换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-01 22:34