推导指向成员的指针模板参数

Deducing pointer-to-member template arguments

本文关键字:指针 参数 成员      更新时间:2023-10-16

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

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;

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

template<auto p_member>
struct Magic
{ };

在 C++17 之前,只有您实现的较长变体才有效。

你可以通过专业化来缩短它,是的。如果你不介意诉诸宏,你几乎可以用 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;