C++ 如何在C+中基于函数模板类型应用不同的#define+;?
我正在使用HDF5库,并试图编写一个模板函数来支持不同数据类型的I/O。我的目标是减少和简化创建所有不同功能所需的复制和粘贴 在HDF5库中,这是写入调用()的格式: 其中许多参数是在我的函数中生成的或作为函数参数传递的。唯一的问题是C++ 如何在C+中基于函数模板类型应用不同的#define+;?,c++,templates,hdf5,template-specialization,C++,Templates,Hdf5,Template Specialization,我正在使用HDF5库,并试图编写一个模板函数来支持不同数据类型的I/O。我的目标是减少和简化创建所有不同功能所需的复制和粘贴 在HDF5库中,这是写入调用()的格式: 其中许多参数是在我的函数中生成的或作为函数参数传递的。唯一的问题是mem_type_id,它被定义为库头文件中的一系列\define子句 是否有一些技巧可以用于根据模板类型更改此设置?我更愿意避免在任何地方都使用std::typeid(T)的大型条件语句。代码在编译时已经非常庞大,因此避免存储不必要的条件所需的字节似乎是可取的。我
mem_type_id
,它被定义为库头文件中的一系列\define
子句
是否有一些技巧可以用于根据模板类型更改此设置?我更愿意避免在任何地方都使用std::typeid(T)
的大型条件语句。代码在编译时已经非常庞大,因此避免存储不必要的条件所需的字节似乎是可取的。我应该实现40多种类型,以便在将来的项目中保持通用性。如果有任何限制我的模板允许我没有定义的类型,这可能会使我减少工作到最低限度
我想到的可能解决方案包括:
所以,虽然我最初被否决,因为这是一个预处理器的声明,我试图选择。这是我想出的一个解决办法 我有两个头文件,第一个是
#pragma once
#include "hdf5.h"
template <typename T> hid_t HdfType();
template<> hid_t HdfType<short>() { return H5T_NATIVE_SHORT; }
template<> hid_t HdfType<unsigned short>() { return H5T_NATIVE_USHORT; }
template<> hid_t HdfType<int> () { return H5T_NATIVE_INT;}
template<> hid_t HdfType<unsigned int> () { return H5T_NATIVE_UINT; }
template<> hid_t HdfType<long> () { return H5T_NATIVE_LONG; }
template<> hid_t HdfType<unsigned long> () { return H5T_NATIVE_ULONG; }
template<> hid_t HdfType<long long> () { return H5T_NATIVE_LLONG; }
template<> hid_t HdfType<unsigned long long> () { return H5T_NATIVE_ULLONG; }
template<> hid_t HdfType<char> () { return H5T_NATIVE_CHAR; }
template<> hid_t HdfType<unsigned char> () { return H5T_NATIVE_UCHAR; }
template<> hid_t HdfType<signed char> () { return H5T_NATIVE_SCHAR; }
template<> hid_t HdfType<float> () { return H5T_NATIVE_FLOAT; }
template<> hid_t HdfType<double> () { return H5T_NATIVE_DOUBLE; }
template<> hid_t HdfType<long double> () { return H5T_NATIVE_LDOUBLE; }
您可以看到HDFType()被放置在正确的位置。这将执行特定数据块的导入。它利用了一个模板,因此我可以轻松地使用它在代码中创建函数,而无需使用重写。通过不定义通用模板和使用模板专门化,我可以将案例限制在我所知道的一般人将在库中使用的情况。如果需要新的案例,我可以构建一个
如果有人有更好的解决方案,请发布。#define
是预处理器指令;在编译器将程序标记化之前对其进行评估;因此,我认为没有机会根据稍后编译步骤中评估的类型选择一组不同的#define
-语句。但我不确定这是否是你的问题。
#pragma once
#include "hdf5.h"
template <typename T> hid_t HdfType();
template<> hid_t HdfType<short>() { return H5T_NATIVE_SHORT; }
template<> hid_t HdfType<unsigned short>() { return H5T_NATIVE_USHORT; }
template<> hid_t HdfType<int> () { return H5T_NATIVE_INT;}
template<> hid_t HdfType<unsigned int> () { return H5T_NATIVE_UINT; }
template<> hid_t HdfType<long> () { return H5T_NATIVE_LONG; }
template<> hid_t HdfType<unsigned long> () { return H5T_NATIVE_ULONG; }
template<> hid_t HdfType<long long> () { return H5T_NATIVE_LLONG; }
template<> hid_t HdfType<unsigned long long> () { return H5T_NATIVE_ULLONG; }
template<> hid_t HdfType<char> () { return H5T_NATIVE_CHAR; }
template<> hid_t HdfType<unsigned char> () { return H5T_NATIVE_UCHAR; }
template<> hid_t HdfType<signed char> () { return H5T_NATIVE_SCHAR; }
template<> hid_t HdfType<float> () { return H5T_NATIVE_FLOAT; }
template<> hid_t HdfType<double> () { return H5T_NATIVE_DOUBLE; }
template<> hid_t HdfType<long double> () { return H5T_NATIVE_LDOUBLE; }
#pragma once
#include "hdf5.h"
#include "HdfTypeTemplate.h"
#include <vector>
template <typename T, int dims=1, int numColumns =1>
void CollectiveHdfBlockImport(hid_t datasetId, long long startRowIndex, long long numRowsToImport, std::vector<T>& data)
{
data.resize(numRowsToImport * numColumns + 10);
hid_t dtplId = CreateCollectiveDataTransferPropertiesList();
hid_t dataspaceId = H5Dget_space(datasetId);
hsize_t start[2] = { 0 }, count[2] = { 0 }, strideAndBlocks[2] = { 1,1 };
count[0] = numRowsToImport;
count[1] = numColumns;
start[0] = startRowIndex;
start[1] = 0;
hid_t memspaceId = H5Screate_simple(dims, count, NULL);
H5Sselect_hyperslab(dataspaceId, H5S_SELECT_SET, start, strideAndBlocks, count, strideAndBlocks);
H5Dread(datasetId, HdfType<T>(), memspaceId, dataspaceId, dtplId, data.data());
H5Sclose(dataspaceId);
H5Sclose(memspaceId);
H5Pclose(dtplId);
}