C++;HDF5提取复合数据类型的一个成员 < >我正在编写一个C++库,它读取另一个库生成的HDF5文件。

C++;HDF5提取复合数据类型的一个成员 < >我正在编写一个C++库,它读取另一个库生成的HDF5文件。,c++,hdf,C++,Hdf,这些hdf5文件包含大量具有各种复合数据类型的复合数据集。我希望把每个复合数据类型翻译成C++结构。 字符串(可变长度或固定大小的字符数组),我想在C++结构中使用STD::string。< /P> 目前,我使用中间的C结构(使用代码> char *< /COD>或 char []/COD>变量),然后转换成最终的C++结构。然而,这导致了大量的样板代码 如果我可以逐个成员提取数据,我可以执行以下操作: std::string name = extract<std::string>(

这些hdf5文件包含大量具有各种复合数据类型的复合数据集。我希望把每个复合数据类型翻译成C++结构。

字符串(可变长度或固定大小的字符数组),我想在C++结构中使用STD::string。< /P>

目前,我使用中间的C结构(使用代码> char *< /COD>或<代码> char []/COD>变量),然后转换成最终的C++结构。然而,这导致了大量的样板代码

如果我可以逐个成员提取数据,我可以执行以下操作:

std::string name = extract<std::string>(d,"name");
std::string name=extract(d,“name”);
其中d是复合数据集


是否可能

我找到了一个有效的解决方案。我把它贴在这里,也许有人会发现它有用。其思想是创建一个CompoundExtractor对象,该对象包含一个缓冲区,在该缓冲区中读取整个化合物。然后,可以使用模板提取方法逐个提取成员。在此阶段,适当的专业化(此处未报告)允许适当处理字符串。 问候,

struct MADNEX\u VISIBILITY\u EXPORT componendextractor
{
/*!
*\brief构造函数
*\param[in]d:数据集
*/
复合抽取器(常量数据集&);
//!析构函数
~componextractor();
/*!
*\返回给定类型化合物的成员
*\param[in]n:成员名称
*/
模板
T extract(const std::string&)const;
/*!
*\返回给定类型化合物的成员
*\param[in]n:成员名称
*/
模板
T提取(常量字符*)常量;
私人:
//!复合数据类型的说明
H5::复合型ctype;
//!复合数据类型的中间存储器
std::矢量数据;
}; // 复合抽取器末端
模板
T componextractor::extract(const char*n)const{
const auto i=this->ctype.getMemberIndex(n);
const auto o=this->ctype.getMemberOffset(i);
return*(重新解释转换(this->data.data()+o));
}//CompoundExtractor的结尾::extract
模板
T componextractor::extract(const std::string&n)const{
const auto i=this->ctype.getMemberIndex(n);
const auto o=this->ctype.getMemberOffset(i);
return*(重新解释转换(this->data.data()+o));
}//CompoundExtractor的结尾::extract
CompoundExtractor::CompoundExtractor(常量数据集&d)
{
const auto dtype=d.getDataType();
if(dtype.getClass()!=H5T\u复合){
抛出(std::runtime_错误(“CompoundExtractor:无效数据集”);
}
这->ctype=H5::CompType(d);
这->data.resize(ctype.getSize());
d、 读取(this->data.data(),ctype);
}
CompoundExtractor::~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;