繁体   English   中英

在运行时确定主要变量类型的函数

[英]A function where the main variables type is determined at run-time

我有一个简单的问题,我不知道如何解决,这是因为使用python并习惯了使用数据类型无关紧要的变量。 我正在使用Windows Task Scheduler及其具有数百万个对象的ITask ...此ITask ...那个。

所以我有一个函数,&取决于参数triggerType(枚举变量),变量trigger的类型将为ITimeTrigger或IBootTrigger……这很难用文字解释,如果您看下面的代码,容易看出我的问题是什么。

通过查看下面的示例,它很容易理解我的问题:

enum meh { I_WANT_A_INT = 50001, I_WANT_A_FLOAT };

bool foo( meh triggerType )
{    
    switch ( triggerType )
    {
        case I_WANT_A_INT:
        {
             int trigger = 10;
        }
        break;
        case I_WANT_A_FLOAT:
        {
             float  trigger  = 10.111;
        }
        break;
        default:
        {
             double  trigger  = 11;
        }
        break;
    }

    trigger  = 5 * trigger ;   // Compile error because trigger is not declared
    cout <<  trigger  << endl;
}

我知道我可以使用的解决方案是:
-我可以重载该函数,并为ITimeTrigger(int)操作提供一个功能,为IBootTrigger(float)提供另一个功能。 我真的不想做这件事,因为该函数真的很长,并且它们之间有很多重复的代码。
-ITimeTrigger和IBootTrigger都从同一对象ITrigger继承,因此我可以将开关外部的触发器var声明为ITrigger,然后将其转换为开关中需要的对象。 现在可以正常工作,但是当我扩展此功能以计划其他类型的任务触发器时,它将不会继承自ITrigger(再次是Win32语义),因此该解决方案将无法工作。

如何声明变量trigger(其数据类型将在运行时确定),以便稍后可以在函数中使用var?

您可以使用模板来避免代码重复。 例如,以上内容可以重写为:

// Common code goes here:
template<typename TriggerType>
void bar(TriggerType trigger)
{
    trigger *= 5;
    std::cout << trigger << std::endl;
}

// Differing code goes here:
void foo(meh trigger_type)
{
    switch (trigger_type) {
    case I_WANT_A_INT:
        bar(10); // invokes the int version
        break;
    case I_WANT_A_FLOAT:
        bar(10.111f); // invokes the float version; note the use of 'f'
        break;
    default:
        bar(11.0); // invokes the double version; note the use of '.0' and lack of 'f'
    }
}

对于那些行为截然不同的类型,您还可以使用bar特殊实例化。

在C ++中,这实际上没有任何意义。 类型在运行时确定。 尽管您可以创建一个类的层次结构,这些类的行为类似于内置类型,重载operator*等,但它们却是多态的,但我会问您为什么要具有这样的混合基本类型的能力?

如果您想为不同类型使用不同版本的函数,但又没有代码重复,那么您可能想看看使用函数模板。 参见例如http://www.parashift.com/c++-faq-lite/templates.html

#include <iostream>
using namespace std;

enum meh { i_want_a_int = 50001, i_want_a_float };

template< class Number >
bool bar( Number trigger )
{
    trigger  *= 5;
    cout <<  trigger  << endl;
    return true;
}

bool foo( meh triggerType )
{    
    switch ( triggerType )
    {
        case i_want_a_int:
            return bar<int>( 10 );
        case i_want_a_float:
             return bar<float>( 10.111f );
        default:
             return bar<double>( 11.0 );
    }
}

int main()
{
    foo( i_want_a_float );
}

顺便说一句,通过为宏保留ALL_UPPERCASE标识符,可以大大减少无意替换文本的机会。

干杯,

模板是可能的解决方案。

它不得不说没有看到更多细节,但是我注意到您说“该函数确实很长,并且包含很多重复代码”。

你可以有:

  1. 单个功能模板
  2. 重构到类模板中,并在基类方法中使用非类型特定的代码可能会很好
  3. 函数的集合,其中一些被模板化,而顶层函数被模板化
  4. 带有某些子例程的重载的顶层模板函数。

注意,您还使用模板将枚举映射到类型:

enum meh { I_WANT_A_INT = 50001, I_WANT_A_FLOAT, I_WANT_A_DOUBLE };

template<meh = I_WANT_A_DOUBLE>
struct TriggerType
{
    typedef double Type;
};
template<>
struct TriggerType<I_WANT_A_INT>
{
    typedef int Type;
};
template<>
struct TriggerType<I_WANT_A_FLOAT>
{
    typedef float Type;
};

template<class T> void setValue(T& t);

template<> void setValue<double>(double& t) { t = 11;}
template<> void setValue<int>(int& t) { t = 10;}
template<> void setValue<float>(float& t) { t = 10.111f;}

template<class T> 
bool fooTyped()
{
    T trigger;
    setValue(trigger);
    trigger *= 5;
    std::cout <<  trigger  << std::endl; 
    return true;
}

bool foo( meh triggerType )
{    
    bool ret = false;
    switch ( triggerType )
    {
        case I_WANT_A_INT:
        {
            ret = fooTyped<TriggerType<I_WANT_A_INT>::Type>(); ;
        }
        break;
        case I_WANT_A_FLOAT:
        {
            ret = fooTyped<TriggerType<I_WANT_A_FLOAT>::Type>(); ;
        }
        break;
        default:
        {
           ret = fooTyped<TriggerType<I_WANT_A_DOUBLE>::Type>(); ;
        }
        break;
    }
    return ret;
}    

void test ()
{
    foo(I_WANT_A_INT);
    foo(I_WANT_A_FLOAT);
    foo((meh)63);
}

注意将枚举映射到类型的调度; 我们需要这个显式样板,因为我们不能使用运行时值来实例化模板。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM