我正在编写一个c ++库,用于读取由另一个库生成的hdf5文件。
那些hdf5文件包含大量具有各种复合数据类型的复合数据集。我希望将每个复合数据类型转换为C ++结构。
对于字符串(可变长度或固定大小的字符数组),我想在C ++结构中使用std :: string。
目前,我使用中间C结构(使用char*
或char[]
变量)然后转换为最终的C ++结构。但是,这会产生许多样板代码。
如果我可以通过成员提取数据成员,我可以执行以下操作:
std::string name = extract<std::string>(d,"name");
其中d是复合数据集。
是否可能
答案 0 :(得分:0)
我找到了一个有效的解决方案。我在这里发布,也许有人会发现它很有用。我们的想法是创建一个CompoundExtractor对象,该对象包含一个缓冲区,其中读取整个化合物。然后,可以使用模板提取方法逐个提取成员。在此阶段,适当的专业化(此处未报告)允许适当处理字符串。 的问候,
struct MADNEX_VISIBILITY_EXPORT CompoundExtractor
{
/*!
* \brief constructor
* \param[in] d: data set
*/
CompoundExtractor(const DataSet&);
//! destructor
~CompoundExtractor();
/*!
* \return a member of the compound of the given type
* \param[in] n: member name
*/
template<typename T>
T extract(const std::string&) const;
/*!
* \return a member of the compound of the given type
* \param[in] n: member name
*/
template<typename T>
T extract(const char *) const;
private:
//! the description of the compound data type
H5::CompType ctype;
//! an intermediate storage for the compound data type
std::vector<char> data;
}; // end of CompoundExtractor
template<typename T>
T CompoundExtractor::extract(const char *n) const{
const auto i = this->ctype.getMemberIndex(n);
const auto o = this->ctype.getMemberOffset(i);
return *(reinterpret_cast<const T *>(this->data.data()+o));
} // end of CompoundExtractor::extract
template<typename T>
T CompoundExtractor::extract(const std::string& n) const{
const auto i = this->ctype.getMemberIndex(n);
const auto o = this->ctype.getMemberOffset(i);
return *(reinterpret_cast<const T *>(this->data.data()+o));
} // end of CompoundExtractor::extract
CompoundExtractor::CompoundExtractor(const DataSet& d)
{
const auto dtype = d.getDataType();
if(dtype.getClass()!=H5T_COMPOUND){
throw(std::runtime_error("CompoundExtractor: invalid data set"));
}
this->ctype = H5::CompType(d);
this->data.resize(ctype.getSize());
d.read(this->data.data(),ctype);
}
CompoundExtractor::~CompoundExtractor() = default;