Как получить объектный тип указателя на нестати c член данных во время компиляции? - PullRequest
1 голос
/ 28 февраля 2020

Предположим, у нас есть простой класс данных, подобный этому:

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 где-то спрятанное в стандарте? Это то, что мне нужно, но я не могу найти ..

Ответы [ 2 ]

3 голосов
/ 28 февраля 2020

Указатели-члены и обычные указатели - это совершенно разные типы. Вы ничего не можете добавить или удалить к go из указателя на элемент в обычном указателе объекта. Вам нужна специальная черта типа.

// 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

1 голос
/ 28 февраля 2020

Если вас не интересуют ссылки, вы можете сделать следующее на месте:

using member_t = std::remove_reference_t<decltype(std::declval<DataObj>().member)>;

Он менее общий, но немного короче, чем другой ответ.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...