Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何在C+中基于函数模板类型应用不同的#define+;?_C++_Templates_Hdf5_Template Specialization - Fatal编程技术网

C++ 如何在C+中基于函数模板类型应用不同的#define+;?

C++ 如何在C+中基于函数模板类型应用不同的#define+;?,c++,templates,hdf5,template-specialization,C++,Templates,Hdf5,Template Specialization,我正在使用HDF5库,并试图编写一个模板函数来支持不同数据类型的I/O。我的目标是减少和简化创建所有不同功能所需的复制和粘贴 在HDF5库中,这是写入调用()的格式: 其中许多参数是在我的函数中生成的或作为函数参数传递的。唯一的问题是mem_type_id,它被定义为库头文件中的一系列\define子句 是否有一些技巧可以用于根据模板类型更改此设置?我更愿意避免在任何地方都使用std::typeid(T)的大型条件语句。代码在编译时已经非常庞大,因此避免存储不必要的条件所需的字节似乎是可取的。我

我正在使用HDF5库,并试图编写一个模板函数来支持不同数据类型的I/O。我的目标是减少和简化创建所有不同功能所需的复制和粘贴

在HDF5库中,这是写入调用()的格式:

其中许多参数是在我的函数中生成的或作为函数参数传递的。唯一的问题是
mem_type_id
,它被定义为库头文件中的一系列
\define
子句

是否有一些技巧可以用于根据模板类型更改此设置?我更愿意避免在任何地方都使用
std::typeid(T)
的大型条件语句。代码在编译时已经非常庞大,因此避免存储不必要的条件所需的字节似乎是可取的。我应该实现40多种类型,以便在将来的项目中保持通用性。如果有任何限制我的模板允许我没有定义的类型,这可能会使我减少工作到最低限度

我想到的可能解决方案包括:

  • 创建返回HDF5类型的专用模板函数 id,其中我对每种类型都有专门化
  • 巨型if语句

  • 所以,虽然我最初被否决,因为这是一个预处理器的声明,我试图选择。这是我想出的一个解决办法

    我有两个头文件,第一个是

    #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);
    }