如何在编译时获取指向非静态数据成员的指针的对象类型?
How to get object type of pointer to non-static data member at compile time?
假设我们有一个像这样的简单数据class:
struct DataObj
{
char member[32];
}
以及指向数据对象中成员的指针类型:
typedef decltype(&DataObj::member) memberObjPtr;
如何推断指针指向的成员变量的类型?
具体来说,我如何获得:
typedef myExpression<memberObjPtr>::type myType;
std::is_same<char[32],myType>::value == true
到目前为止我尝试了什么:
std::remove_pointer
std::remove_reference
std::decay
没有成功。
标准中是否隐藏了 remove_member_object_pointer 之类的东西?这是我需要但似乎找不到的东西..
成员指针和普通指针是完全不同的类型。从成员指针到常规对象指针,您无法添加或删除任何内容。你需要一个专门的类型特征。
// General case
// If a type isn't supported by a partial specialization
// it will use this case and fail to compile
template<class T>
struct mbrptr_to_type;
// Partial specialization that matches any data member pointer type
// T C::* means "pointer to member of type `T` in class `C`"
template<class T, class C>
struct mbrptr_to_type<T C::*> {
// Save the member type so it can be retrieved
using type = T;
};
// Helper alias
template<class T>
using mbrptr_to_type_t = typename mbrptr_to_type<T>::type;
使用您的测试用例:
struct DataObj
{
char member[32];
};
// myType will be char[32]
using myType = mbrptr_to_type_t<decltype(&DataObj::member)>;
// Verification
#include <type_traits>
static_assert(std::is_same<char[32], myType>::value);
实例:Godbolt
如果您不关心引用,可以就地执行以下操作:
using member_t = std::remove_reference_t<decltype(std::declval<DataObj>().member)>;
它不太笼统,但比其他答案短一点。
假设我们有一个像这样的简单数据class:
struct DataObj
{
char member[32];
}
以及指向数据对象中成员的指针类型:
typedef decltype(&DataObj::member) memberObjPtr;
如何推断指针指向的成员变量的类型? 具体来说,我如何获得:
typedef myExpression<memberObjPtr>::type myType;
std::is_same<char[32],myType>::value == true
到目前为止我尝试了什么:
std::remove_pointer
std::remove_reference
std::decay
没有成功。 标准中是否隐藏了 remove_member_object_pointer 之类的东西?这是我需要但似乎找不到的东西..
成员指针和普通指针是完全不同的类型。从成员指针到常规对象指针,您无法添加或删除任何内容。你需要一个专门的类型特征。
// General case
// If a type isn't supported by a partial specialization
// it will use this case and fail to compile
template<class T>
struct mbrptr_to_type;
// Partial specialization that matches any data member pointer type
// T C::* means "pointer to member of type `T` in class `C`"
template<class T, class C>
struct mbrptr_to_type<T C::*> {
// Save the member type so it can be retrieved
using type = T;
};
// Helper alias
template<class T>
using mbrptr_to_type_t = typename mbrptr_to_type<T>::type;
使用您的测试用例:
struct DataObj
{
char member[32];
};
// myType will be char[32]
using myType = mbrptr_to_type_t<decltype(&DataObj::member)>;
// Verification
#include <type_traits>
static_assert(std::is_same<char[32], myType>::value);
实例:Godbolt
如果您不关心引用,可以就地执行以下操作:
using member_t = std::remove_reference_t<decltype(std::declval<DataObj>().member)>;
它不太笼统,但比其他答案短一点。