C++类成员函数返回类型推断、模板封装getter和setter

C++类成员函数返回类型推断、模板封装getter和setter,第1张

意图

有一批类,每个具有多个私有属性,以及这些属性的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;
}

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/langs/1325784.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-06-12
下一篇2022-06-12

发表评论

登录后才能评论

评论列表(0条)

    保存