在下面的示例代码中,类 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;
}
最佳答案
你会得到这样的东西:
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
是私有(private)的,因此在 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::*;
};
关于c++ - 如何解析成员指针非类型模板参数的组件类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35262278/