Я ищу способ получить смещения членов данных класса C ++, который не относится к POD.
Вот почему:
Я хочу хранить данные в формате HDF5, который кажется наиболее подходящим для моего типа материал (вывод численного моделирования), но, возможно, это библиотека, скорее ориентированная на C. Я хочу использовать его через интерфейс C ++, для чего мне потребуется объявить такие типы хранилищ (следующая документация от 1CompType.html # a16 "rel =" noreferrer "> здесь и здесь (раздел 4.3.2.1.1)):
class example {
public:
double member_a;
int member_b;
} //class example
H5::CompType func_that_creates_example_CompType() {
H5::CompType ct;
ct.insertMember("a", HOFFSET(example, member_a), H5::PredType::NATIVE_DOUBLE);
ct.insertMember("b", HOFFSET(example, member_b), H5::PredType::NATIVE_INT);
return ct;
} //func_that_creates_example_CompType
где HOFFSET - это специфичный для HDF макрос, который использует offsetof.
Проблема, конечно, в том, что как только класс-пример становится немного более функциональным, он больше не относится к типу POD, и поэтому использование offsetof даст неопределенные результаты.
Единственный обходной путь, который я могу придумать, - сначала экспортировать данные, которые я хочу сохранить, в более простую структуру, а затем передать их в HDF. Однако это связано с копированием данных, чего HDF пытается избежать (и почему у них есть этот CompType, который позволяет библиотеке обращаться к вашим объектам для сохранения их данных в файл).
Так что я надеялся, что у вас появятся идеи получше. В идеале я бы искал переносимое решение этой проблемы, но если этого не произойдет, вы могли бы дать мне идею, которая работает на x86 и x86_64 с GCC, я уже был бы безмерно благодарен.
----- добавлено позже: -----
Грег Хьюгилл предложил ниже хранить данные в простой структуре, а затем построить фактический класс, унаследовав от него. В частности, для HDF, я думаю, это может практически не сработать. Более сложный сценарий использования, чем указано выше:
class base_pod {
public:
double member_a;
int member_b;
}; //class base_pod
class derived_non_pod : private base_pod {
public:
//the following method is only virtual to illustrate the problem
virtual double get_member_a() {return member_a; }
}; //class derived_non_pod
class that_uses_derived_non_pod {
public:
void whatever();
private:
derived_non_pod member_c;
}; //class that_uses_derived_non_pod
Теперь, когда мы храним экземпляры класса that_uses_dehibited_non_pod, мы не можем описать его структуру памяти, как если бы у него был base_pod как member_c. Это приведет к неправильному смещению, потому что производное_non_pod добавляет забавные вещи (вроде таблицы виртуальных функций, я думаю?).