我必须制作一个元编程模板,我必须检测数组的大小。 所以模板检测到数组的大小:
template<typename T, size_t N>
size_t arraylen( T(&)[N] )
{ return N; }
这样可以正常使用,但剂量适用于此模板
//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 *&amp;)'
当我把N i M的const值设为其工作时:
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 :(得分:3)
这至少是使用此模板的重要部分 - 它只会在传递实际数组时才有效。当您尝试在函数内部使用它时,函数参数已经从数组衰减到指针。由于无法在指针上调用模板,因此编译失败。
为了使工作正常,您可以(例如)将函数转换为模板,该模板也接收对数组的引用。这会将参数的“数组”性质保留在函数本身中(就像在模板中一样)。
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()
就可以了
答案 1 :(得分:2)
这是因为当你将数组传递给一个函数时,它们不再是数组,而是已经衰减为指针。数组和指针几乎可以互换,但不同之处在于指针当然没有大小。