получить тип членской точки-члена

Я хотел бы извлечь тип члена, на который указывает указатель члена.

template<someType myClass::*member>
void demo(myClass& instance, void* ptr) {
instance.*member = *reinterpret_cast<someType*>(ptr);  // can the someType in this line be deduced from member?
}

Я пытался с помощью decltype как предложено в комментариях, однако у меня есть проблемы с этим:

instance.*member= static_cast<decltype(instance.*member)>((*buffer)[offset]);

buffer это std::shared_ptr<std::vector<uint8_t>>,
someType является uint32_t

Я получаю следующее сообщение об ошибке:

ошибка: недопустимый static_cast от типа
__ __gnu_cxx :: __ alloc_traits> :: value_type
{aka unsigned char} ‘для ввода ‘uint32_t& {иначе неподписанный int&}»

Насколько я понимаю decltype(instance.*member) с member определяется как uint32_t instance::*member дает ссылка uint32_t& скорее, чем uint32_t, Я попытался передать экземпляр по значению, и ошибка остается. Я в курсе std::remove_reference Тем не менее, я не понимаю, как ссылка становится там в первую очередь.

Дальнейшее улучшение было бы, если бы я мог извлечь someType без экземпляра класса. Однако я понятия не имею, как этого добиться, в то время как я могу получить класс без указателя, используя std lib, например:

template <T*>
struct removePointer {
typedef T type;
}

Я понятия не имею, как написать это в форме, где я могу получить someType часть класса, не зная класса в первую очередь. Я мог бы написать что-то вроде следующего, однако мне все равно пришлось бы явно передавать класс naem и typename, есть ли способ извлечь их автоматически? Кроме того, следующее не компилируется в первую очередь (http://ideone.com/8VlKO4):
#включают
использование пространства имен std;

template <class C,typename T, T C::*v>
struct getPointerType {
typedef T type;
};

class Test {
int value;
};

int main() {
int Test::*member=nullptr;
cout << typeid(getPointerType<Test, int, decltype(member)>::type) << std::endl;
return 0;
}

1

Решение

Честно говоря, немного трудно понять, чего вы пытаетесь достичь, поэтому я сосредоточусь на обновленной части.

Очевидно, что вы не можете передавать типы (производные от decltype) в качестве аргументов значения для шаблона. Более того, вы не можете передавать значения не constexpr в качестве аргументов шаблона (поэтому вы не можете просто вставить member переменная в аргумент шаблона и ожидать его компиляции).

Тем не менее, вы можете положиться на компилятор, чтобы иметь возможность вывести правильную функцию для вызова не costexpr переменная:

template <class C, typename T>
T getPointerType(T C::*v);

class Test {
int value;
};

int main() {
int Test::*member=nullptr;
cout << typeid(decltype(member)).name() << std::endl;
cout << typeid(decltype(getPointerType(member))).name() << std::endl;
return 0;
}

Выше будет напечатано:

M4Testi //int Test::*
i       //int

Конечно, можно «злоупотреблять» подстановкой шаблонов еще больше:

template <typename M>
struct getPointerType {
template <typename C, typename T>
static T get_type(T C::*v);

typedef decltype(get_type(static_cast<M>(nullptr))) type;
};

class Test {
int value;
};

int main() {
int Test::*member=nullptr;
cout << typeid(getPointerType<decltype(member)>::type).name() << std::endl;
return 0;
}

Результатом будет ожидаемое «я».

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]