考虑具有成员变量的类,如下所示:
struct A {
int a;
char b;
};
struct B {
double c;
bool d;
};
是否可以声明一个接受其模板的模板类 参数指向成员的任何一个成员的指向成员对象的参数 在上面的课程? 接受通用指针到成员对象的类可以是 声明和使用如下:
template<typename Class, typename Type, Type (Class::*Member)>
struct Magic
{ };
// Usage:
typedef Magic<A, int, &A::a> MagicWithA_a;
不幸的是,传递Class
和Type
非常麻烦
每次Magic
模板参数使最终指针起作用。
有没有办法让部分专业化推断出这些论点,
例如?也就是说,如何声明typedef Magic<&B::c> MagicWithB_c;
typedef Magic<&A::b> MagicWithA_b;
类来制作。{1}}类
以下定义有效吗?
{{1}}
答案 0 :(得分:6)
使用C ++ 17,您可以使用auto
非类型模板参数:
template<auto p_member>
struct Magic
{ };
在C ++ 17之前,只有您实施的较长版本才有效。
答案 1 :(得分:3)
你可以通过专业化来缩短它,是的。如果您不介意使用宏,则可以使用c++11获得所需的语法。首先,主要模板专业化:
template<typename T, T pm>
struct MagicImpl; // Undefined for most types
然后是指向成员的指针的部分特化,我们可以在其中自由添加我们希望推导出的参数:
template<class Class, typename Type>
struct MagicImpl<Type Class::*, Type (Class::*Member)> {
};
最后,我们需要使用decltype
从指向成员的表达式中获取指向成员类型的指针,我们将其隐藏在上述宏之后:
#define MAGIC(...) MagicImpl<decltype(__VA_ARGS__), __VA_ARGS__>
你可以按如下方式使用它:
typedef MAGIC(&B::c) MagicWithB_c;
typedef MAGIC(&A::b) MagicWithA_b;