Функции / функторы как параметры шаблона. Их можно хранить?
представьте, что у меня есть следующая свободная функция и функтор:
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_)
{}
};
или что-то в этом роде