我想存储一对成员 get/set 函数以供以后与 T 类型的对象一起使用。
我有一个部分工作的设置,见下文。然而问题仍然存在:
笔记:
Make( get, set )
的来电者不应该提供 lambdas。那就是把问题委托(delegate)给他!? template <typename T, typename V, typename G, typename S>
class GetSet
{
public:
constexpr GetSet( G member_get, S member_set ) : Get( member_get ), Set( member_set )
{ }
auto GetValue( const T& t ) const
{
return ( t.*Get )( );
}
void SetValue( T& t, V&& value ) const
{
( t.*Set )( std::forward<V>( value ) );
}
private:
G Get;
S Set;
};
template <typename T, typename ValueType, typename S>
constexpr auto Make( ValueType( T::*member_get )( ) const, S member_set )
{
using G = ValueType( T::* )( ) const;
return GetSet<T, ValueType, G, S>( member_get, member_set );
}
最佳答案
不知道你为什么需要这个,但最简单的解决方案如下。
#include <utility>
template <class F> struct ClassType;
template <typename Ret, typename TCls, typename... Args>
struct ClassType<Ret (TCls::*)(Args...)> {
using type = TCls;
};
template <typename Ret, typename TCls>
struct ClassType<Ret (TCls::*)() const> {
using type = TCls;
};
template<class TFnGet, class TFnSet>
class GetSet
{
public:
using TGet = TFnGet;
using TSet = TFnSet;
public:
inline GetSet(TGet fnGet, TSet fnSet)
: m_fnGet(fnGet), m_fnSet(fnSet)
{
}
template<class T>
inline decltype(auto) GetValue(T&& r) const
{
static_assert(std::is_same<typename std::remove_cv<typename std::remove_reference<T>::type>::type, typename ClassType<TFnGet>::type>::value, "wrong type of r?");
return (r.*m_fnGet)();
}
template<class T, class TValue>
inline void SetValue(T&& r, TValue&& value)
{
static_assert(std::is_same<typename std::remove_cv<typename std::remove_reference<T>::type>::type, typename ClassType<TFnSet>::type>::value, "wrong type of r?");
(r.*m_fnSet)(std::forward<TValue>(value));
}
private:
TGet m_fnGet;
TSet m_fnSet;
};
template<class TGet, class TSet>
GetSet<TGet, TSet> MakeGetSet(TGet fnGet, TSet fnSet)
{
static_assert(std::is_same<typename ClassType<TGet>::type, typename ClassType<TSet>::type>::value, "members of different classes?");
return GetSet<TGet, TSet>(fnGet, fnSet);
}
验证:class A
{
public:
void Set(int i) {}
int Get() const { return 0;}
void SetRef(char& ch) {}
A& GetRef() { return *this;}
void SetRRef(float&& ) {}
int&& GetRRef() { return 1; }
void SetConstRef(const char& ch) {}
int GetNotConst() { return 0;}
};
int main(int argc, char* argv[])
{
A a;
auto gs = MakeGetSet(&A::Get, &A::Set);
auto gsRef = MakeGetSet(&A::GetRef, &A::SetRef);
auto gs2 = MakeGetSet(&A::GetRRef, &A::SetRRef);
auto gsNonConst = MakeGetSet(&A::GetNotConst, &A::SetConstRef);
int x = gs.GetValue(a);
gs.SetValue(a, 2);
const A& ra = a;
x = gs.GetValue(ra);
A& r = gsRef.GetValue(a);
char ch =' ';
gsRef.SetValue(a, ch);
x = gs2.GetValue(a);
gs2.SetValue(a, 1.1f);
x = gsNonConst.GetValue(a);
gsNonConst.SetValue(a, ch);
std::cout << "ok\n";
return 0;
}
关于c++ - 存储成员 get/set 函数供以后使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63614100/