2015-06-23 3 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, обычные указатели функций (или статические элементы) и lambdas, все, не беспокоясь о случаях или сохраняя информацию. –

+0

'void *' или, еще лучше - 'ParentInterface *' – Amartel

+3

Показать пример примера использования. Похоже, что может быть лучшее решение в целом. –

ответ

1

Я думаю std::function и std::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

Смежные вопросы