Функции / функторы как параметры шаблона. Их можно хранить?

представьте, что у меня есть следующая свободная функция и функтор:

void myFreeFunction(void)
{
    cout << "Executing free function" << endl;
}

struct MyFunctor
{
    void operator()(void)
    {
        cout << "Executing functor" << endl;
    }
};

как вышеписанной по ответ, я могу передать свою функцию или функтор в качестве аргумента шаблона для другой функции:

template <typename F>
void doOperation(F f)
{
    f();
}

а потом звоните:

doOperation(myFreeFunction);
doOperation(MyFunctor());

пока все хорошо. А что если я хочу что-то вроде следующего:

template<typename Callback>
class MyClass
{
private:
    Callback mCallback;

public:
    MyClass(){}

    void execute()
    {
        mCallback();
    }
};

в этом случае я указываю функцию / функтор, когда я объявляю класс, но не вызываю его позже. Это работает для функторы:

MyClass<MyFunctor> myClass1;
myClass1.execute();

но не для функций:

MyClass<myFreeFunction> myClass2;
myClass2.execute();

компилятор говорит:

ошибка C2923:' MyClass':' myFreeFunction 'не является допустимым аргументом типа шаблона для параметра'Callback'

что достаточно справедливо... но как ее оформить?

Примечание: я знаю о функции std::и может в конечном итоге использовать это. Это заметно медленнее, хотя, так что я смотрю на все опции.

спасибо,

Дэвид

1 ответов


проблема в том, что freefunction-это не тип, а элемент a of (int в этом случае указатель на функцию.

чтобы исправить эту проблему, вам нужно передать функцию в, в конструкции, однако вам все равно нужно знать точный тип.

myclass<call_back_t> my_class(call_back);

EDIT: в c++11 тип можно получить из decltype(call_back)

однако получение обратного вызова может быть хлопотно, часто намного проще создать функцию генератора

//this should be in the namespace of the class or a static member of it
template<FuncType>
myclass<FuncType> make_class(FuncType func)
{
     return myclass<FuncType>(func);
}
//called like
myclass mc=make_class(&my_callback);

не изменять конструктор

template<typename CallBack>
myclass{
private:
   CallBack call_back;
public:
   myclass(CallBack call_back_)
   : call_back(call_back_)
   {}
};

или что-то в этом роде