使用外部函数的C ++模板

时间:2011-07-26 19:50:57

标签: c++ templates external

C ++允许在模板规范实现中使用外部函数吗?我想做的是制作一个BLAS / LAPACK包装器(CBLAS不会为我剪掉它,我需要一些不在那里且在外部BLAS中的功能),有点像这样

extern "C" {
    void saxpy_(int* n, const float* const sa, const float* const sx, int* incx, float* sy, int* incy);
    void daxpy_(int* n, const double* const sa, const double* const sx, int* incx, double* sy, int* incy);
}
namespace matrix {
template<class T>
void ax_plus_y(const T a, const Matrix<T, Dynamic, Dynamic>& x, Matrix<T, Dynamic, Dynamic>& y) {
    y += a * x;
}

template<>
void ax_plus_y<float>(const float a, const Matrix<float, Dynamic, 1>& x, Matrix<float, Dynamic, 1>& y) {
    int n = x.size();
    int incx = x.innerStride();
    int incy = y.innerStride();
    saxpy_(&n, &a, x.data, &incx, y.data(), &incy);
}

template<>
void ax_plus_y<double>(const double a, const Matrix<double, Dynamic, 1>& x, Matrix<double, Dynamic, 1>& y) {
    int n = x.size();
    int incx = x.innerStride();
    int incy = y.innerStride();
    daxpy_(&n, &a, x.data, &incx, y.data(), &incy);
}
}

这只是我需要的一小部分,但这有可能吗?我实际上不能只使用一个函数,因为我需要对每种数据类型进行不同的外部调用。

P.S。 Matrix来自Eigen,与概念无关。

编辑:澄清一下,这就是g ++引发的:

error: template-id ‘ax_plus_y<float>’ for ‘void matrix::ax_plus_y(float, const Eigen::Matrix<float, -0x00000000000000001, 1>&, Eigen::Matrix<float, -0x00000000000000001, 1>&)’ does not match any template declaration

3 个答案:

答案 0 :(得分:1)

当然可以,为什么不呢?

答案 1 :(得分:0)

我看到的问题是你宣布了三件事:

template<class T>
void ax_plus_y(const T a, const Matrix<T, Dynamic, Dynamic>& x, 
    Matrix<T, Dynamic, Dynamic>& y);

template<>
void ax_plus_y<float>(const float a, const Matrix<float, Dynamic, 1>& x, 
    Matrix<float, Dynamic, 1>& y);

template<>
void ax_plus_y<double>(const double a, const Matrix<double, Dynamic, 1>& x, 
     Matrix<double, Dynamic, 1>& y);

使用Matrix<double, Dynamic, 1>的特化的函数签名与使用Matrix<double, Dynamic, Dynamic>的常规函数​​签名不匹配,因此编译器不会将特化与常规模板相关联。我不认为编译器会跳过隐式类型转换圈,以使其适合您。

编辑:关于你的一般“是否可能”的问题:是的,但这需要付出很多努力,你可能要考虑编写某种代码生成程序让你免于疯狂。

我在几年前做过,但不是MatrixVector类,只有const T*, size_t对。我的目标是易读性(BLAS / LAPACK函数名称更多是关于简洁而不是清晰度),支持其他库,如FFTW和SSE,以及支持这些包之外的类型。我们的想法是,您将使用常规例程,它将为您的平台生成最佳代码。不幸的是,我无法开源,而且还有十年的支持。

在你的情况下,你将不得不写下这样的东西:

template<class T, long long D1=Dynamic, long long D2=Dynamic>
void ax_plus_y(const T a, const Matrix<T, D1, D2>& x, Matrix<T, D1, D2>& y) {
    y += a * x;
}

template<long long D1=Dynamic>
void ax_plus_y<float, D1, 1>(const float a, const Matrix<float, D1, 1>& x, Matrix<float, D1, 1>& y) {
    int n = x.size();
    int incx = x.innerStride();
    int incy = y.innerStride();
    saxpy_(&n, &a, x.data, &incx, y.data(), &incy);
}

template<long long D2=Dynamic>
void ax_plus_y<float, 1, D2>(const float a, const Matrix<float, 1, D2>& x, Matrix<float, 1, D2>& y) {
    int n = x.size();
    int incx = x.outerStride();
    int incy = y.outerStride();
    saxpy_(&n, &a, x.data, &incx, y.data(), &incy);
}

并重复double

答案 2 :(得分:0)

模板函数中的extern函数没有问题。参见例如以下代码片段工作正常:

http://codepad.org/lF8AKwPV

#include <iostream>
#include <math.h>

template<typename T>
void doit(T number)
{
   std::cout << cos(number) << std::endl;
}

template<>
void doit<float>(float number)
{
   std::cout << "a float: " << cos(number) << std::endl;
}

int main()
{
  doit((double)0.0);
  doit((float)1.0);
}

也许这是一个问题,第一个模板定义在名称空间“矩阵”而其他模板定义不是?