Страница указателя cppreference дает несколько примеров того, как использовать указатели на элементы данных. Но что, если я хочу хранить их в одном контейнере? Например:
class C {
int i;
double d;
};
std::vector<???> v{&C::i, &C::d};
Я знаю, что могу использовать для этого std::any, но, может быть, есть что-то вроде void * для простых указателей?
И связанный вопрос. std::any, насколько я понимаю, сохраняет typeid, чтобы проверить, плохой ли каст. При использовании указателей на элементы данных могу ли я использовать их для получения правильного приведения, например:
C c;
c.*(std::cast<??? &C::*>(v[0])) = 42;
Буду признателен за ссылки, где можно прочитать об указателях на элементы данных, мне удалось найти слишком мало!
Если вы хотите выбросить информацию о типе только для того, чтобы вернуть ее позже с помощью приведения, вы делаете что-то неправильно.
Но что, если я хочу хранить их в одном контейнере? -- XY Проблема? «X» мы хотели бы знать, «Y» — это то, что вы хотите хранить указатели на элементы данных.
@Someprogrammerdude Я хочу создать аналог golang json-тегов для разбора json-файлов. В частности, я хочу создать адаптер класса, который будет хранить привязки между именем поля json (std::string) и местом записи этого поля в классе (указатель на элемент данных). Затем, учитывая экземпляр класса, я хочу перебрать вектор и заполнить экземпляр класса значениями json.
@PaulMcKenzie Да, вы правы, но этот вопрос касается не только решения исходной проблемы, но и изучения способов работы с тем, чего я не мог найти достаточно в Интернете.
@Nkamil Я понятия не имею о Голанге. Как работают существующие анализаторы JSON на основе C++? То, что вы хотите сделать, похоже на отражение, а в C++ нет встроенной такой возможности.
Вместо хранения указателя на поле данных сохраните функцию std::function, которая получает строковое представление данных и устанавливает это поле данных.
@n.m.couldbeanAI Можете ли вы уточнить, пожалуйста? Как тогда я буду создавать класс-адаптер? Передача указанной пользователем функции std:: для каждого поля класса, который я хочу десериализовать?
@PaulMcKenzie да, я пытаюсь решить проблему отсутствия отражения в C++, явно заполняя адаптер класса (помощник) полями и именами членов класса (я хочу десериализовать его) :)
std::vector<std::function<void(C&, std::string_view)>> v { [](C& c, std::string_view s){c.i = std::stoi(s);}, [](C& c, std::string_view s){c.d = std::stod(s);}}; (не проверялось).





Как сохранить указатели на элементы данных разных типов в контейнере?
Вам нужно перечислить все возможные типы. C++ — статически типизированный язык. Например:
#include <vector>
#include <variant>
struct C {
int i;
double d;
};
std::vector<std::variant<int C::*, double C::*>> v{&C::i, &C::d};
может быть, есть что-то вроде void * для простых указателей?
(Печально) Нет. Указатели на члены — это достаточно волшебно.
Могу ли я использовать его, чтобы получить правильный состав, что-то вроде:
Да, вы можете использовать его «вот так».
#include <vector>
#include <any>
#include <iostream>
struct C {
int i;
double d;
};
std::vector<std::any> v{&C::i, &C::d};
int main() {
C c;
c.i = 1;
std::cout << c.*std::any_cast<int C::*>(v[0]) << '\n';
}
Какую первоначальную и основную проблему вам необходимо решить? Зачем вам нужно хранить указатели на отдельные переменные-члены? Как это решает исходную проблему?