Шаблоны C ++, использующие внешние функции - PullRequest
1 голос
/ 26 июля 2011

позволяет ли C ++ использовать внешние функции в реализациях спецификаций шаблонов?Что я хочу сделать, так это создать оболочку для BLAS / LAPACK (CBLAS не подрезает ее для меня, мне нужна пара функций, которых нет и есть во внешнем BLAS), примерно так*

Это всего лишь фрагмент того, что мне нужно, но возможно ли это вообще?Я не могу использовать только одну функцию, потому что мне нужны разные внешние вызовы для каждого типа данных.

PS * 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 ]

1 голос
/ 26 июля 2011

Конечно, почему бы и нет?

0 голосов
/ 27 июля 2011

Нет проблем с внешними функциями в шаблонных функциях.См., Например, следующий фрагмент кода, который отлично работает:

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

Возможно, проблема в том, что первое определение шаблона находится в пространстве имен "матрица", а остальные«т

0 голосов
/ 27 июля 2011

Я вижу проблему в том, что вы объявляете три вещи:

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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...