获取成员指针的成员类型

Obtain type of member having pointer to member

本文关键字:成员 类型 成员类 指针 获取      更新时间:2023-10-16

我正在尝试编写一个模板类,该类将接受任何类型,作为参数,该类型具有某些公共成员,可以用作索引(类型INT,简短,无符号,无符号,ETC)。我希望我的模板类接受要使用的对象的类型,以及我的模板类应用作"键"字段的此类字段。

我写了下面的东西(只是一个示例,可以让您了解我要如何使用它),但它不起作用。问题在于,我试图使用一个指针作为成员的指针作为指定为"值"类型的字段的信息,如果我的模板类使用以获取键。我想使用velltype获取尖端字段的类型,但它行不通。

是否有一种方法可以获取Poiter指向会员的字段类型?我尝试了衰减功能,但没有成功。我不想拥有" int a ::*"我只想获得" int"。

#include <iostream>
#include <vector>
using namespace std;
template <class V, class M, M member>
struct MyClass
{
    using key_type = decltype(member);
    vector<key_type> v;
    MyClass()
    {
        v.push_back(1);
        // ERROR - error: no matching function for call to 'std::vector<int A::*, std::allocator<int A::*> >::push_back(int)'
    }
};
struct A 
{ 
    int x; 
    int key;
};
int main()
{
    MyClass<A, decltype(&A::key), &A::key> mc;
}

tl; dr :对模板参数的一些小更正:

template <class C, typename Mem, Mem C::*member>
struct MyClass {
    using key_type = Mem;
    vector<key_type> v;
    MyClass()
    {
        v.push_back(1);
    }
};

和实例化:

MyClass<A, decltype(A::key), &A::key> mc;

将做到这一点。

说明:

  1. 您希望第三个参数是指向您通过的第一个参数的类成员的指针。这需要指向成员语法C::*的指针。Mem类型是" Pointee"的类型。

  2. 要获得成员的类型,而不是"成员指针"的类型,您需要使用成员访问表达式或合格的ID提供decltype。因此,那里的变化。


您可以通过仅将指针传递给成员类型(就像最初一样),并使用元函数从中提取相关信息来将模板参数的量减少到2。

template<typename T>
struct point_to_mem;
// Meta-function to extract type information from a pointer to a member.
template<class C, typename T>
struct point_to_mem<T C::*> {
    using member_type = T;
    using class_type  = C;
};
template <typename PointToMem, PointToMem member>
struct MyClass {
    using key_type = typename point_to_mem<PointToMem>::member_type;
    vector<key_type> v;
    MyClass()
    {
        v.push_back(1);
    }
};
// ...
MyClass<decltype(&A::key), &A::key> mc;

最后,使用C 17,您可以使它真正经济,并将模板参数减少到1:

template <auto member>
struct MyClass {
    using key_type = typename point_to_mem<decltype(member)>::member_type;
    // As before
};
// ...
int main()
{
    MyClass<&A::key> mc;
}