
有一批类,每个具有多个私有属性,以及这些属性的Getter和Setter
class Any
{
std::string S;
public:
std::string GetS() const
{
return S;
}
void SetS(std::string _S)
{
S = _S;
}
};
Any A;
现在做一个工具,在仅能使用类名和属性名的情况下,绑定到v8(也就是提供getter和setter)
提示下文模板中:
T代表类、R代表成员类型、C代表类名、P代表成员名、V代表值
思路一不保证没写错 QAQ
用模板类,但内部还是用了GetS,没法复用
// 结合 decltype 推断类成员函数的返回值
template <class C, class R, class... Args>
R GetRetValue(R (C::*)(Args...)const);
template <typename T, typename R>
struct Wp
{
static R getter()
{
T* self = &A;
return self->GetS();
}
static void setter(R S)
{
T *self = &A;
self->SetS(S);
}
};
#define MakeGetter(T, P) Wp<T, decltype(GetRetValue(&T::Get##P))>::getter()
#define MakeSetter(T, P, V) Wp<T, decltype(GetRetValue(&T::Get##P))>::setter(V)
int main()
{
//Wp::setter("234");
MakeSetter(Any, S, "234");
// cout << Wp::getter() << endl;
cout << MakeGetter(Any, S) << endl;
}
思路二
用宏取代模板
template <class C, class R, class... Args>
R GetRetValue(R (C::*)(Args...)const);
#define MakeGetter(T, P) []() -> decltype(GetRetValue(&T::Get##P))\
{ T *self = &A; return self->Get##P(); }
#define MakeSetter(T, P) [](decltype(GetRetValue(&T::Get##P)) S) \
{ T *self = &A; self->Set##P(S); }
int main()
{
auto G = MakeGetter(Any, S);
auto S = MakeSetter(Any, S);
S("234");
cout << G() << endl;
}
思路三
使用成员函数指针作为模板变量
// 声明 Wp 的模板列表,分别是T1的类型是什么,T1类型的变量……
template <typename T1, T1, typename T2, T2>
struct Wp;
// 声明Gt和St的类型,分别为 R(T::*)()const 和 void(T::*)(R)
template <class T, class R, R(T::*Gt)()const, void(T::*St)(R)>
// T1为 R(T::*)()const,T的函数指针类型,无参数,返回值为R
// T2为 void(T::*)(R),R为参数,无返回值
// Gt和St声明在上方,内容由外部传入
struct Wp<R(T::*)()const, Gt, void(T::*)(R), St>
{
static R getter()
{
T *self = &A;
return (self->*Gt)();
}
static void setter(R S)
{
T *self = &A;
(self->*St)(S);
}
};
#define MakeGetter(T, P) Wp<decltype(&T::Get##P), &T::Get##P, decltype(&T::Set##P), &T::Set##P>::getter
#define MakeSetter(T, P) Wp<decltype(&T::Get##P), &T::Get##P, decltype(&T::Set##P), &T::Set##P>::setter
int main()
{
// Wp::setter("234");
MakeSetter(Any, S)("234");
// cout << Wp::getter();
cout << MakeGetter(Any, S)() << endl;
return 0;
}
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)