根据运行时参数执行整数模板化函数

根据运行时参数执行整数模板化函数

本文介绍了根据运行时参数执行整数模板化函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我经常有一些原型行为,这些行为会基于某种设计方法生成输出.我对设计方法进行了模板化,从而实现了我需要的许多功能.但是,有时设计方法是在运行时给出的,因此通常需要我编写一个巨大的switch语句.通常看起来像这样:

enum class Operation
{
    A, B
};


template<Operation O>
    void execute();

template<>
    void execute<A>()
    {
        // ...
    }

template<>
    void execute<B>()
    {
        // ...
    }

void execute(Operation o)
{
    switch (o)
    {
    case Operation::A: return execute<Operation::A>();
    case Operation::B: return execute<Operation::B>();
    }
}

我对是否有人为该系统找到了一种不错的模式感到好奇-这种方法的主要缺点是,如果实现新的枚举,则必须键入所有受支持的枚举并在多个位置进行维护. /p>

e:我应该补充一点,弄乱编译时模板的原因是允许编译器在HPC中内联方法以及继承constexpr属性.

e2:实际上,我想我要问的是让编译器使用隐式开关结构生成所有可能的代码路径.也许是一些递归模板魔术?

解决方案

如果您真的想利用模板完成此任务,则可以使用类似于.

// Here second template argument default to the first enum value
template<Operation o, Operation currentOp = Operation::A>
// We use SFINAE here. If o is not equal to currentOp compiler will ignore this function.
auto execute() -> std::enable_if<o == currentOp, void>::type
{
    execute<currentOp>();
}

// Again, SFINAE technique. Compiler will stop search if the template above has been instantiated and will ignore this one. But in other case this template will be used and it will try to call next handler.
template<Operation o, Operation currentOp = Operation::A>
void execute()
{
    return execute<o, static_cast<Operation>(static_cast<int>(currentOp) + 1)(c);
}

I often have some prototype behaviour that generates output based on some design method. I template the design method, which enables a lot of functionality I need. However, sometimes the design method is given at runtime, so I'm usually required to write a huge switch statement. It usually looks like this:

enum class Operation
{
    A, B
};


template<Operation O>
    void execute();

template<>
    void execute<A>()
    {
        // ...
    }

template<>
    void execute<B>()
    {
        // ...
    }

void execute(Operation o)
{
    switch (o)
    {
    case Operation::A: return execute<Operation::A>();
    case Operation::B: return execute<Operation::B>();
    }
}

I'm curious as to whether anyone has figured out a nice pattern for this system - the main drawbacks of this method is that one has to type out all the supported enumerations and do maintenance several places if new enumerations are implemented.

e: I should add that the reasons for messing with compile-time templates is to allow the compiler to inline methods in HPC as well as inherit constexpr properties.

e2: in effect, I guess what I'm asking is to have the compiler generate all the possible code paths using an implicit switch structure. Perhaps some recursive template magic?

解决方案

If you really want to utilize templates for this task you can use technique similar to this one.

// Here second template argument default to the first enum value
template<Operation o, Operation currentOp = Operation::A>
// We use SFINAE here. If o is not equal to currentOp compiler will ignore this function.
auto execute() -> std::enable_if<o == currentOp, void>::type
{
    execute<currentOp>();
}

// Again, SFINAE technique. Compiler will stop search if the template above has been instantiated and will ignore this one. But in other case this template will be used and it will try to call next handler.
template<Operation o, Operation currentOp = Operation::A>
void execute()
{
    return execute<o, static_cast<Operation>(static_cast<int>(currentOp) + 1)(c);
}

这篇关于根据运行时参数执行整数模板化函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-31 00:14