Я написал небольшой фрагмент кода, в котором я могу вызывать функции установки и получения, упакованные в функтоид, используя шаблоны mem_fun.
Теперь я хотел бы использовать этот подход поверх иерархии классов, где каждый класс может иметь геттер и сеттер, которые можно зарегистрировать как пару в векторе или массиве, чтобы при необходимости можно было вызывать геттер и сеттер. GUIObject и GUICompositeObject являются примерами классов из описанной иерархии классов. К сожалению,bound_mem_fun_t для объектов имеют разные типы, и поэтому я не знаю, как интегрировать их в массив/вектор указателей на функторы.
В С++ 11 я бы использовал std::function. Есть ли способ эмулировать это в С++ 98?
Поскольку наш компилятор поддерживает только С++98, я не могу использовать новые возможности С++11 или С++14. Также не допускается повышение.
#include <functional>
class GUIObject
{
int m_Alpha;
public:
void SetAlpha(int a) { m_Alpha = a;};
int GetAlpha() {return m_Alpha;};
};
class GUICompositeObject: public GUIObject
{
int m_NumOfChilds;
public:
void SetNumOfChilds(int NumOfChilds) { m_NumOfChilds = NumOfChilds;};
int GetNumOfChilds() {return m_NumOfChilds;};
};
template<typename T>
struct bound_mem_fun_t
{
bound_mem_fun_t(std::mem_fun_t<int, T> GetFunc, std::mem_fun1_t<void, T, int> SetFunc, T* o) :
m_GetFunc(GetFunc), m_SetFunc(SetFunc), obj(o) { } ;
int operator()() { return m_GetFunc(obj); } ;
void operator()(int i) { m_SetFunc(obj, i); } ;
std::mem_fun_t<int, T> m_GetFunc;
std::mem_fun1_t<void, T, int> m_SetFunc;
T* obj;
};
int main()
{
GUIObject kGUIObject;
GUICompositeObject kCompObj;
bound_mem_fun_t<GUIObject> GUIObjectFunc(std::mem_fun(&GUIObject::GetAlpha), std::mem_fun(&GUIObject::SetAlpha), &kGUIObject);
GUIObjectFunc(17);
int ii = GUIObjectFunc();
bound_mem_fun_t<GUICompositeObject> GUICompObjectFunc(std::mem_fun(&GUICompositeObject::GetNumOfChilds), std::mem_fun(&GUICompositeObject::SetNumOfChilds), &kCompObj);
GUICompObjectFunc(17);
int iChilds = GUICompObjectFunc();
return 0;
}
Вот полное решение после ответа @filmors:
#include <functional>
#include <vector>
#include <iostream>
class GUIObject
{
int m_Alpha;
public:
void SetAlpha(int a) { m_Alpha = a;};
int GetAlpha() {return m_Alpha;};
};
class GUICompositeObject: public GUIObject
{
int m_NumOfChilds;
public:
void SetNumOfChilds(int NumOfChilds) { m_NumOfChilds = NumOfChilds;};
int GetNumOfChilds() {return m_NumOfChilds;};
};
struct bound_mem_fun_base
{
virtual int operator()() =0;
virtual void operator()(int) =0;
};
template<typename T>
struct bound_mem_fun_t : public bound_mem_fun_base
{
bound_mem_fun_t(std::mem_fun_t<int, T> GetFunc, std::mem_fun1_t<void, T, int> SetFunc, T* o) :
m_GetFunc(GetFunc), m_SetFunc(SetFunc), obj(o) { } ;
virtual int operator()() { return m_GetFunc(obj); } ;
virtual void operator()(int i) { m_SetFunc(obj, i); } ;
std::mem_fun_t<int, T> m_GetFunc;
std::mem_fun1_t<void, T, int> m_SetFunc;
T* obj;
};
template<typename T> bound_mem_fun_t<T>* make_setter(std::mem_fun_t<int, T> GetFunc, std::mem_fun1_t<void, T, int> SetFunc, T* o)
{
return new bound_mem_fun_t<T> (GetFunc, SetFunc, o);
}
int main()
{
GUIObject kGUIObject;
GUICompositeObject kCompObj;
std::vector<bound_mem_fun_base*> kBoundVector;
kBoundVector.push_back(new bound_mem_fun_t<GUIObject> (std::mem_fun(&GUIObject::GetAlpha), std::mem_fun(&GUIObject::SetAlpha), &kGUIObject));
kBoundVector.push_back(new bound_mem_fun_t<GUICompositeObject> (std::mem_fun(&GUICompositeObject::GetNumOfChilds), std::mem_fun(&GUICompositeObject::SetNumOfChilds), &kCompObj));
kBoundVector.push_back(make_setter<GUIObject> (std::mem_fun(&GUIObject::GetAlpha), std::mem_fun(&GUIObject::SetAlpha), &kGUIObject));
kBoundVector.push_back(make_setter<GUICompositeObject> (std::mem_fun(&GUICompositeObject::GetNumOfChilds), std::mem_fun(&GUICompositeObject::SetNumOfChilds), &kCompObj));
for (int i = 0; i < 4 ; i++)
{
(*kBoundVector[i])(i*10);
int res = (*kBoundVector[i])();
std::cout << "Getter result " << res << "\n";
}
return 0;
}
К сожалению, функция make_setter на самом деле не сокращает время создания функтора. Любые идеи будут приветствоваться.