alias de um modelo de função

Eu criei um distribuidor de CPU que compila as mesmas funções com diferentes opções de compilação em arquivos de objetos diferentes. Para que meu código acesse as mesmas funções em diferentes arquivos de objetos, preciso atribuir um nome diferente às funções de cada arquivo de objeto.

Em C (ou C ++), eu faria algo assim no arquivo de cabeçalho para as declarações da função.

typedef float MyFuncType(float a);

MyFuncType  myfunc_SSE2, myfunc_SSE41, myfunc_AVX, myfunc_AVX2, myfunc_AVX512

Mas agora eu quero modelos de função para as declarações. Meu código real atualmente se parece mais com isso

//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

Estas são apenas declarações em um arquivo de cabeçalho. As definições de função estão em um arquivo de origem separado, compilado em um arquivo de objeto diferente para cada nome de função. As definições são mais ou menos assim

//kernel.cpp
#include "kernel.h"
template<typename TYPE, unsigned N, typename VALUES>
void FUNCNAME(int32_t *buffer, VALUES & v) {
    //code
}

Então eu compilo assim

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

O arquivomain.cpp é outro arquivo de origem que precisa conhecer apenas as declarações de função para que o vinculador possa vinculá-las às definições nos outros arquivos de objeto. Se parece com isso

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

Mas no meu arquivo "kernel.h" é irritante (e propenso a erros) repetir isso para cada alteração no nome da função. Eu quero algo como o seguinte (que eu sei que não funciona).

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

Existe uma maneira ideal para isso que separa as declarações e definições e me permite renomear declarações de função de modelo idênticas?

questionAnswers(1)

yourAnswerToTheQuestion