2015-06-23 186 views
0

是否有可能從模板中存儲類而不使整個類成爲模板?模板和函數指針

任務:

我有兩個功能,V1無參數和參數V2, 如果V1被稱爲地方什麼也沒有發生與使用(),如果V2被稱爲地方使用()應執行function_ptr與我從DoSometh(T *)獲得的實例。

例如

class MyClass 
    { 
     //v1 no parameters 
     void DoSomething() 
     { 
     } 

     //v2 with parameter 
     template<class T> 
     void DoSomething(T* instance, void (T::*func)()) 
     { 
     store somewhere?? = instance; 
     } 

     void Use() 
     { 
     //if DoSometh(T* instance) was used before 
     if(instance != NULL) 
     { 
      (*instance->)//call function pointer from DoSomething(T*,void (T::*)()) 
     } 
     } 
    } 

std::function problem 
update: 


class Timer : public ITickable 
{ 
    std::function<void()> test; //adding this does weird things 

    virtual void Tick() {} 
} 

class MyClass 
{ 
    ITickable* tickable_; 

void Tick() 
{ 
    tickable_->Tick(); //let's assume it points to a Timer obj. 
} 


} 
+1

你*有*使用函數指針?你不能使用標準庫用於所有可調用函數的模板嗎?然後,您可以傳遞一個'std :: function'對象,泛型函數對象,'std :: bind'對象,普通(或靜態成員)函數指針和lambda表達式,而不用擔心實例或存儲信息。 –

+0

'void *'或者甚至更好 - 'ParentInterface *' – Amartel

+3

顯示一個真實的用例示例。看起來好像可能有更好的解決方案。 –

回答

1

我覺得std::functionstd::bind(C++ 11)並完成你想要什麼,在評論中已經建議。您的Timer類的簡化實物模型可能是:

class Timer 
{ 
    std::function<void()> m_task; 

public: 
    template <typename T> 
    void setTask(T &instance, void (T::*fcn)()) // consider T const & if applicable 
    { 
     m_task = std::bind(fcn, &instance); 
    } 

    void fire() 
    { 
     if (m_task) // std::function overloads operator bool()                   
      m_task(); 
    } 
}; 

setTask被調用的對象和成員函數,可以在此對象上調用,將創建一個std::function對象(你可以選擇做這當然在構造函數中)。當定時器觸發時,將檢查該對象(使用operator bool(),由std::function提供),並且如果它是可調用的(例如,之前調用過setTask()),它將調用該函數。

例如:

class MyClass 
{ 
public: 
    void func() 
    { 
     std::cout << "Hi from MyClass\n"; 
    } 
}; 

class MyOtherClass 
{ 
public: 
    void func() 
    { 
     std::cout << "Hi from MyOtherClass\n"; 
    } 
}; 


int main(int argc, char **argv) 
{ 
    MyClass x1; 
    MyOtherClass x2; 

    Timer t1, t2; 
    t1.setTask(x1, &MyClass::func); 
    t2.setTask(x2, &MyOtherClass::func); 

    t1.fire(); 
    t2.fire(); 
} 
+0

hmm,不知何故,當我寫std :: function m_task;在我的類定義中,沒有任何工作了 – jeromintus

+0

繼承和std :: function有問題嗎? – jeromintus

+0

如果例如,計時器有一個基類ITickable? 'class Timer:public ITickable {}' 可能會導致問題嗎? – jeromintus