簡體   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