C ++模板实例:避免长时间交换机 [英] C++ template instantiation: Avoiding long switches

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

问题描述

我有根据整数模板参数的类。在我的程序一点我想使用这个模板的一个实例,根据此参数在运行时确定的值。下面是一个简单的例子展示我怎么会去这当前,用一个大的switch语句:

 的#include<串GT;
#包括LT&;&iostream的GT;
#包括LT&;&type_traits GT;模板<无符号A>
结构包装{
    typedef的类型名称的std ::有条件< A == 1,整型,浮点> ::型数据类型;
    数据类型内容[A];
    无效美孚(){
        性病::法院LT&;< A<<的std :: ENDL;
    };
};INT主(INT ARGC,CHAR *的argv [])
{
    标准::字符串ARG =的argv [1];
    INT arg_int =的std :: Stoi旅馆(ARG);    开关(arg_int){
    情况1: {
        包装&所述1为卤素;瓦;
        w.foo();
        打破;
    }
    案例2:{
        包装2>瓦;
        w.foo();
        打破;
    }
    情况3:{
        包装3;>瓦;
        w.foo();
        打破;
    }
    默认:
        返回1;
    };    返回0;
}

这将很快得到笨重一旦我有没有只有一个参数 A ,但在各种组合多个模板参数。让我们假设,在现实中有是实施作为一个模板参数一个很好的理由。

有没有一种方法几乎相同的case语句,例如更换巨大的switch语句利用升压元编程的一些魔术或preprocessor破解?

我非常希望能够写类似如下:

  INSTANTIATE_DEPENDING(I,{1,2,3},
            {
                包装< I>瓦;
                w.foo();
            }
    );


解决方案

您可以使用可变参数模板,也许是这样的:

 的#include< cstdlib>
#包括LT&;串GT;INT主(INT ARGC,CHAR *的argv [])
{
    如果(!ARGC = 2){返回EXIT_FAILURE; }    handle_cases&。1,3,4,9,11>(性病:: Stoi旅馆(的argv [1]));
}

实施

 模板< INT ...>结构intList中{};无效handle_cases(INT,intList中<>){/ *默认情况下,* /}模板< INT I,诠释... N>无效handle_cases(INT I,intList中< I,N ...>)
{
    如果(I = I!){返回handle_cases(ⅰ,intList中与所述; N ...>()); }    包装< I>瓦;
    w.foo();
}模板< INT ... N>无效handle_cases(int i)以
{
    handle_cases(ⅰ,intList中与所述; N ...>());
}

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;
}

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.

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]));
}

Implementation:

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 ++模板实例:避免长时间交换机的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆