2017-06-17 57 views
0

我正在使用HDF5庫,並試圖編寫一個模板函數來支持具有不同數據類型的I/O。目標只是爲了減少和簡化複製和粘貼,我需要做的是創建所有不同的功能。如何在C++中基於函數模板類型應用不同的#define?

在HDF5庫這是寫調用(documentation here)格式:

H5Dwrite(hid_t dataset_id, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id, hid_t xfer_plist_id, const void * buf) 

許多這些參數都在我的函數生成或作爲函數的參數傳遞。唯一的問題是mem_type_id,它定義爲庫的頭文件中的一系列#define子句。

是否有一些技巧可以用來根據模板類型進行更改?我寧願避免在任何地方都有一個巨大的條件聲明std::typeid(T)。代碼在編譯時已經很龐大,因此避免存儲不必要的條件所需的字節是明智的。我應該實施超過40種類型來保留這個通用的未來項目。如果無論如何要限制我的模板允許我沒有定義的類型,那可能會讓我將工作量降到最低。

可能的解決方案,我有,雖然包括:

  1. 創建返回的HDF5 類型ID,其中i爲每個類型的特專門的模板功能。
  2. 巨人if語句
+1

'#define'是一個預處理指令;在編譯器甚至標記程序之前對它進行評估;所以我沒有機會以某種方式根據稍後編譯步驟中評估的類型選擇一組不同的'#define'語句。但我不確定這是否是您的問題。 –

回答

1

所以,當我本來下投票,因爲這是我想選擇一個預處理器聲明。這是我制定的解決方案。

我有兩個頭文件第一個是這個

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

此文件從#define返回預定義的句柄數。第二個文件包含以下內容

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

您會看到HDFType()放置在正確的位置。這將執行特定數據塊的導入。它使用了一個模板,所以我可以輕鬆地使用它在我的代碼中創建函數,而無需重新使用它。通過不定義一般模板和使用模板專業化,我可以將案例限制在我知道的一般人們將在圖書館中使用的情況中。如果需要一個新案例,我可以構建一個。

如果有人有更好的解決方案,請發佈它們。

相關問題