我已經創建了一個CPU調度程序,它將具有不同編譯選項的相同函數編譯到不同的目標文件中。爲了讓我的代碼在不同的目標文件中訪問相同的函數,我需要爲每個目標文件中的函數賦予不同的名稱。在C(或C++)中,我會在頭文件中爲函數的聲明做類似的事情。函數模板的別名
typedef float MyFuncType(float a);
MyFuncType myfunc_SSE2, myfunc_SSE41, myfunc_AVX, myfunc_AVX2, myfunc_AVX512
但現在我想要聲明的函數模板。我的真實代碼目前看起來更像這樣
//kernel.h
template <typename TYPE, unsigned N, typename VALUES>
void foo_SSE2(int32_t *buffer, VALUES & v);
template <typename TYPE, unsigned N, typename VALUES>
void foo_SSE41(int32_t *buffer, VALUES & v);
...
template <typename TYPE, unsigned N, typename VALUES>
void foo_AVX512(int32_t *buffer, VALUES & v);
#if INSTRSET == 2 // SSE2
#define FUNCNAME foo_SSE2
#elif INSTRSET == 5 // SSE4.1
#define FUNCNAME foo_SSE41
...
#if INSTRSET == 9 // AVX512
#define FUNCNAME foo_AVX512
#endif
這些只是頭文件中的聲明。函數定義位於單獨的源文件中,該文件被編譯爲每個函數名稱的不同目標文件。該定義是這個樣子
//kernel.cpp
#include "kernel.h"
template<typename TYPE, unsigned N, typename VALUES>
void FUNCNAME(int32_t *buffer, VALUES & v) {
//code
}
然後我這樣進行編譯
gcc -c -O3 -msse2 kernel.cpp -o kernel_sse2.o
gcc -c -O3 -msse4.1 kernel.cpp -o kernel_sse41.o
...
gcc -c -O3 -mavx512f kernel.cpp -o kernel_avx512.o
gcc -O3 main.cpp kernel_sse2.o kernel_sse41.o ... kernel_avx512.o
文件main.cpp
是隻需要知道函數的聲明,以便鏈接可以將它們鏈接到定義另一個源文件在其他對象文件中。它看起來像這樣
void dispatch(void) {
int iset = instrset_detect();
if (iset >= 9) {
fp_float1 = &foo_AVX512<float,1>;
}
else if (iset >= 8) {
fp_float1 = &foo_AVX2<float,1>;
}
...
else if (iset >= 2) {
fp_float1 = &foo_SSE2<float,1>;
}
}
int main(void) {
dispatch();
fp_float1(buffer, values);
}
但在我的文件「kernel.h當」這很煩人(且容易出錯),重複這個在函數名的每一個變化。我想要類似以下內容(我知道這是行不通的)。
template <typename TYPE, unsigned N, typename VALUES>
typedef void foo(int32_t *buffer, VALUES & v);
foo foo_SSE2, foo_SSE41, foo_SSE_AVX, foo_AVX2, foo_AVX512
有沒有一種理想的方式來分離聲明和定義,並允許我簡單地重命名相同的模板函數聲明?
您可以讓預處理器完成這項工作。 – Columbo
您可以使用模板typedef(使用'')[Live Demo](https://ideone.com/v7wDhj)保存參數輸入。但不能在一行中聲明幾個模板函數:/ – Jarod42
C++ 11具有'using'關鍵字用於模板別名 – ftynse