推导指向成员的模板参数

时间:2018-01-27 18:06:17

标签: c++ templates

考虑具有成员变量的类,如下所示:

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;

不幸的是,传递ClassType非常麻烦 每次Magic模板参数使最终指针起作用。

有没有办法让部分专业化推断出这些论点, 例如?也就是说,如何声明typedef Magic<&B::c> MagicWithB_c; typedef Magic<&A::b> MagicWithA_b; 类来制作。{1}}类 以下定义有效吗?

{{1}}

2 个答案:

答案 0 :(得分:6)

使用C ++ 17,您可以使用auto非类型模板参数:

template<auto p_member>
struct Magic
{ };

在C ++ 17之前,只有您实施的较长版本才有效。

答案 1 :(得分:3)

你可以通过专业化来缩短它,是的。如果您不介意使用宏,则可以使用获得所需的语法。首先,主要模板专业化:

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;