在下面的示例代码中,B类有三个模板参数。我想知道前两个论点是否可以从第三个论证中推断出来,我认为它包含了所有必要的信息。现在我正在使用一个宏,以避免在各种组合中多次繁琐地重复相同的名称。我认为应该有更好的方法。
在 main 中,我展示了我想写的理想内容。
B类的目标是: 1)变量成员指针应明确地是类的非类型模板参数 2)它应该适用于不同的类(例如A1,A2)和不同类型的成员变量。 如何重写B类以实现上述目标并允许仅使用一个模板参数进行定义?
#include <iostream>
struct A1
{
int m_n;
A1() : m_n(10) {}
};
struct A2
{
double m_x;
A2() : m_x(2.1) {}
};
#define XXX(cls, member) cls, decltype(cls::member), &cls::member
// I would like B to have only the last template argument
template <typename C, typename T, T C::*P>
struct B
{
B(C& cls) : m_c(cls), m_v(cls.*P) {};
void set(T v) { m_v = v; }
void save() { m_c.*P = m_v; }
C& m_c;
T m_v;
};
int main()
{
A1 a1; std::cout << "a1.n=" << a1.m_n << std::endl;
A2 a2; std::cout << "a2.x=" << a2.m_x << std::endl;
// This is what I write
typedef B<XXX(A1,m_n)> m1_n_t;
typedef B<XXX(A2,m_x)> m2_x_t;
// This is what I woukd like to write
//typedef B<&A1::m_n> m1_n_t;
//typedef B<&A2::m_x> m2_x_t;
// this is how I use it
m1_n_t b1(a1); b1.set(5); b1.save(); std::cout << "a1.n=" << a1.m_n << std::endl;
m2_x_t b2(a2); b2.set(3.4); b2.save(); std::cout << "a2.x=" << a2.m_x << std::endl;
return 0;
}
答案 0 :(得分:4)
你会有这样的事情:
template <class Type>
struct member_object;
template<typename RetType, typename ClassType>
struct member_object<RetType ClassType::*> {
using return_type = RetType;
using class_type = ClassType;
using member_type = RetType ClassType::*;
};
请注意,在A
中,n
是私有的,因此除非您将其公开,否则无法在decltype(&A::n)
中进行编译。
如果在编译时需要实际的指针,那么你必须明确地将它作为另一个模板参数传递,如下所示:
template <class PtrType, PtrType Ptr>
struct member_object;
template<typename RetType, typename ClassType, RetType ClassType::* Ptr>
struct member_object<RetType ClassType::*, Ptr> {
using return_type = RetType;
using class_type = ClassType;
using member_type = RetType ClassType::*;
};