【发布时间】:2013-06-02 15:24:28
【问题描述】:
我必须制作一个元编程模板,我必须在其中检测数组的大小。 所以检测数组大小的模板:
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*&)'
当我输入 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 风格的,没有像 std::vector 或其他的 C++
【问题讨论】:
-
return (*a)*(*b)+IloczynSkalarny<N-1>(++a,++b);这是未定义的行为。 -
但是这个模板工作正常我没有这个模板的问题。
-
未定义的行为并不意味着它不会编译。相反,它可能不会按照您的预期去做,或者在看似随机的情况下失败。
-
@Aku 无论如何,你应该修复它。如果它被另一个编译器、另一个版本的编译器或不同的优化级别搞砸了,请不要感到惊讶。
标签: c++ arrays size detect template-meta-programming