C ++ метапрограммирование определить размер массива

Я должен сделать шаблон метапрограммирования, где я должен определить размер массива.
Итак, шаблон, который определяет размер массива:

template<typename T, size_t N>
size_t arraylen( T(&)[N] )
{ return N; }

Это работает нормально, но Dosent работает с этим шаблоном

//Template to calculate Vector*Vector
template<int N>  double IloczynSkalarny(double *a,double *b) {
return (*a)*(*b)+IloczynSkalarny<N-1>(++a,++b);
}
template<>  double IloczynSkalarny<1>(double *a,double *b) {
return (*a)*(*b);
}
//Here we calculate the row of matrix using Vector*Vector template
template<int M,size_t I> double row_vec(double *A,double *v) {
return IloczynSkalarny<M>(A+I*M,v);
}

//Looping thru matrix rows
template<int N,int M> struct  matrix_vec_c {
static void matrix_vec(double *A,double *v,double *u) {
u[N-1]=row_vec<M,N-1>(A,v);
matrix_vec_c<N-1,M>::matrix_vec(A,v,u);
}
};

template<int M> struct  matrix_vec_c<0,M> {
static void matrix_vec(double *A,double *v,double *u) {}
};//Calling template
template<size_t N,size_t M> inline void matrix_vec(double A[],double v[],double u[]) {
matrix_vec_c<N,M>::matrix_vec(A,v,u);
}

Этот шаблон хорошо работает, когда я даю параметры N i M, как это

double x[] = {1, 1, 0};
double A[] = {1, 0, 0,

2, -5, 1};
double y[2];
matrix_vec<2,3>(A,x,y);

Но мне нужно вызвать matrix_vec так:

matrix_vec(A,x,y);

Где никакие параметры N i M не передаются в шаблон. Поэтому я должен определить размер массивов.
Поэтому я делаю шаблон так:

inline void matrix_vec(double A[],double v[],double u[]) {
int  N = arraylen(v);
int M = arraylen(u);
matrix_vec_c<N,M>::matrix_vec(A,v,u);
}

Но я получаю ошибка: нет подходящей функции для вызова arraylen (double *&)»

Когда я ставлю постоянные значения N i M, его работы:

inline void matrix_vec(double A[],double v[],double u[]) {
int const N = 3;
int const M = 3;
matrix_vec_c<N,M>::matrix_vec(A,v,u);
}

Конечно, это не имеет смысла, потому что переданные массивы имеют различные размеры.
Функция шаблона arraylen работает нормально, но в моем шаблоне нет, что я делаю неправильно?

PS
Массивы в стиле C не имеют C ++, как std :: vector или другие

0

Решение

Это, по крайней мере, большая часть смысла использования этого шаблона в первую очередь — он будет работать только тогда, когда ему передан реальный массив. Когда вы пытаетесь использовать его внутри функции, параметр функции уже распался из массива в указатель. Поскольку вы не можете вызвать шаблон по указателю, компиляция завершится неудачно.

Чтобы все заработало, вы можете (для одного примера) превратить функцию в шаблон, который также получает ссылку на массив. Это сохранит природу аргумента «массив» в самой функции (так же, как в вашем шаблоне).

template <class T, size_t N>
size_t sum(T(&matrix)[N]) {
// use matrix. For this example, we'll sum its elements:
size_t total = 0;
for (size_t i=0; i<N; i++)
total += matrix[i];
return total;
}

Который вы могли бы использовать что-то вроде этого:

int main() {
int x[] = {1, 3, 5, 7, 9};
std::cout << sum(x);
return 0;
}

Обратите внимание, что в этом случае вам не нужно arraylen, потому что размер массива (N) доступен напрямую.

Другой способ заставить это работать (лучший способ, IMO) — просто сказать «нет» массивам. Пройти std::vectorНапример, и вся проблема просто исчезает полностью — вам не нужен специальный взлом шаблона, чтобы получить длину в первую очередь, вы просто вызываете your_vector.size() и это все хорошо.

2

Другие решения

Это потому, что когда вы передаете массивы в функцию, они больше не являются массивами, а распадаются на указатели. Массивы и указатели в значительной степени взаимозаменяемы, но с той разницей, что указатель, конечно, не имеет размера.

2

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector