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
答案 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>
的常规函数签名不匹配,因此编译器不会将特化与常规模板相关联。我不认为编译器会跳过隐式类型转换圈,以使其适合您。
编辑:关于你的一般“是否可能”的问题:是的,但这需要付出很多努力,你可能要考虑编写某种代码生成程序让你免于疯狂。
我在几年前做过,但不是Matrix
或Vector
类,只有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函数没有问题。参见例如以下代码片段工作正常:
#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);
}
也许这是一个问题,第一个模板定义在名称空间“矩阵”而其他模板定义不是?