1

我必须制作一个元编程模板,我必须在其中检测数组的大小。所以检测数组大小的模板:

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++

4

2 回答 2

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)就是对数组说不。例如,通过 a std::vector,整个问题就完全消失了——你不需要特殊的模板技巧来获得长度,你只需调用your_vector.size()就可以了。

于 2013-06-02T15:31:46.947 回答
2

这是因为当您将数组传递给函数时,它们不再是数组,而是衰减为指针。数组和指针几乎可以互换,但不同的是指针当然没有大小。

于 2013-06-02T15:27:25.240 回答