转发模板函数的参数

时间:2016-12-25 06:04:19

标签: c++

数值库通常具有类型指定的函数,它们具有几乎相同的函数名和参数,例如cblas_[sdcz]gemm,具体取决于输入的类型。为了允许函数重载并因此调用cblas_tgemm,我编写了这些函数的包装器,如:

inline
void cblas_tgemm(const  CBLAS_LAYOUT Layout, const  CBLAS_TRANSPOSE TransA,
                 const  CBLAS_TRANSPOSE TransB, const INT M, const INT N,
                 const INT K, const float alpha, const float *A,
                 const INT lda, const float *B, const INT ldb,
                 const float beta, float *C, const INT ldc)
{
    cblas_sgemm(Layout, TransA,
                 TransB, M, N,
                 K, alpha, A,
                 lda, B, ldb,
                 beta, C, ldc);
}
inline
void cblas_tgemm(const  CBLAS_LAYOUT Layout, const  CBLAS_TRANSPOSE TransA,
                 const  CBLAS_TRANSPOSE TransB, const INT M, const INT N,
                 const INT K, const double alpha, const double *A,
                 const INT lda, const double *B, const INT ldb,
                 const double beta, double *C, const INT ldc)
{
    cblas_dgemm(Layout, TransA,
                 TransB, M, N,
                 K, alpha, A,
                 lda, B, ldb,
                 beta, C, ldc);
}

显然,这非常烦人,因为我需要迭代所有函数参数。是否有更好的方法来转发所有论点?例如,使用error: redefinition of ‘template<class ... Params> void {anonymous}::cblas_tgemm(Params&& ...)’

,以下代码无效
template <typename ...Params>
void cblas_tgemm(Params&&... params)
{
    cblas_sgemm(std::forward<Params>(params)...);
}
template <typename ...Params>
void cblas_tgemm(Params&&... params)
{
    cblas_dgemm(std::forward<Params>(params)...);
}

1 个答案:

答案 0 :(得分:2)

SFINAE可能有所帮助:

#define RETURNS(...) \
  -> decltype(__VA_ARGS__ )\
  { return __VA_ARGS__; }

template <class ...Params>
auto cblas_tgemm(Params&&... params)
RETURNS(cblas_sgemm(std::forward<Params>(params)...))

现在只有在表达式有效时才会应用此重载。

重复签名和多个重载有效等问题可能存在问题。但这是起点。