-2

I have a question about template function. This is my first time using template. I may lack of some basis. I am confusing about the type of variables I should use. What is the meaning of int N after the template? I regard N as a flexible integer. Is A[N][N] 2d array variable or a pointer? What about b[N]? I have an example using all inputs as non-pointer ones. But the hint from the Xcode tells me all variable are pointer. Here is the hint "LUsolve(double (*A)[N], const double *b, double *x)". But I tried my pointers variable, not working. The function LUfactorize and LUsolve_internal are also template functions. It is too long. I don't post all code.

template < int N >
bool LUsolve( double A[N][N],  const double b[N],  double x[N]  ) 
{ 
  double B[N][N]; 
  int i, j, p[N], status;
  for (i = 0; i < N; i++) {
    for (j = 0; j < N; j++) {
      B[i][j] = A[i][j];
    }
  }
  status = LUfactorize(B, p); 
  if (status != 0) 
  {
   printf("Failed in the LU factorization.\n"); 
   return false;
  }
  LUsolve_internal(B, p, b, x);
  return true;
}


template <int N>
int LUfactorize(double A[N][N], int p[N])

template <int N>
void LUsolve_internal(double A[N][N], const int p[N],
                  const double b[N], double x[N])

Here is the example I work on. The error is "No matching function for call to 'LUsolve'". How can I fix it?

bool cubicspline (double const *knots , double const *knots_value, 
double *coef, int const N)
{

  double x_i = 0;
  double x_Km1 = 0;
  double x_K = 0;
  double d_i = 0;
  double d_Km1 = 0;
  double A [N][N];

  for ( int i = 0; i < N; i++)
  {
    A[i][0] = 1;
    A[i][1] = knots[i];
    for ( int j = 2; j < N; j++)
    {
      x_i = ( (knots[i] > knots[j-2]) ? (knots[i] - knots[j-2]) : 0 );
      x_Km1 = ( (knots[i] > knots [N-2]) ? (knots[i] - knots[N-2]) : 0 );
      x_K = ( (knots[i] > knots [N-1]) ? (knots[i] - knots[N-1]) : 0 );
      d_i = (x_i * x_i * x_i - x_K * x_K * x_K) / ( knots[N-1] -     knots[j-2] );
      d_Km1 = ( x_Km1 * x_Km1 * x_Km1 - x_K * x_K * x_K) / ( knots[N-1] - knots[N-2] );
      A[i][j] = d_i - d_Km1;
    }
   }

bool status = LUsolve( A , knots_value, coef); // Here is the error.
Yue
  • 23
  • 6
  • 2
    Your variable names are quite confusing, specially using both lower and upper case of the same later (see `b` and `B`). The time spent writing a few extra characters will repay itself countless times by the time you and everyone else will save trying to figure out what your code is doing. – François Andrieux Jul 17 '17 at 15:12
  • The language doesn't allow passing arrays in function parameters, so they all decay to pointers. – Rakete1111 Jul 17 '17 at 15:13
  • B is a matrix and b is the right hand side of the linear system, e.g. Bu=b. – Yue Jul 17 '17 at 15:14
  • Pretty simple: `N` will be replaced with the integer constant you provide at instantiation. – user0042 Jul 17 '17 at 15:14
  • Why the array could be used in the example? – Yue Jul 17 '17 at 15:20
  • Read up on arrays and pointers in your favourite C++ book. Despite what it looks like, all the arguments *are* pointers. – molbdnilo Jul 17 '17 at 15:21
  • I have changed my example. Can someone help me fix it? – Yue Jul 17 '17 at 15:46

2 Answers2

0

Having template< int N > in a sense means that N is another parameter to the function - it's just like a normal variable. The big difference is that it must be specified at compile time. This lets you declare arrays of fixed size N when you can't normally declare an array of size determined by a variable - the only reason it works here is because N is known at compile-time, so it's "like" writing int x[5].

See here for a similar question, and the linked wikipedia article on Template Metaprogramming for a better appreciation of the compile-time nature.

If as you said, this is your first time using templates, you should probably start with more "normal" usecases (as generic parameters) to get a feel for how they're compile-time, before using them like this.

hnefatl
  • 5,860
  • 2
  • 27
  • 49
0

About template function

It is a function template. You get a template function by instantiating the function template.

What is the meaning of int N after the template?

It is a (non-type) template parameter. When the template is instantiated, the values for the template parameters (and types for template type parameters, which your template does not have) must be provided - either explicitly, or deduced from the non-template arguments by the compiler)

Is A[N][N] 2d array variable or a pointer?

It is a pointer. But only because it is a function argument. If it was a declaration of an array that was not a function parameter, then it would have been an array variable.

You cannot pass arrays by value into functions, and an array argument declaration is sneakily (and confusingly in my opinion) replaced with a pointer. The type is actually double (*A)[N] i.e. a pointer to an array of N doubles.

Here is the example I said. The inputs are not pointers.

Like above, your inputs really are pointers. Function parameter const double p[2] actually means double const *p.

Why the array could be used in the example?

Because arrays implicitly decay to pointer to first element.

eerorika
  • 232,697
  • 12
  • 197
  • 326
  • Thank you for the answer. I have changed the example to mine. Can you give some advise? – Yue Jul 17 '17 at 15:45
  • @Yue did the compiler not mention any candidates for the function? I suspect that you forgot to define the template before calling it. – eerorika Jul 17 '17 at 15:50
  • @Yue You can however use references to arrays, e.g. `double (&A)[N][N]` – Caleth Jul 17 '17 at 15:56
  • @user2079303 The complier gives the candidate function as 'LUsolve'. The first function is in the LU.h file. My example is in another header file. I have included LU.h. What do you mean by define template? Define template in my example function? – Yue Jul 17 '17 at 15:57
  • @Yue does it not mention anything about not being able to convert arguments? Read the whole error. – eerorika Jul 17 '17 at 15:58
  • @user2079303 The whole error is "No matching function for call to 'LUsolve'". I think it is from the wrong match of variable type. Probably it is from the matrix or 2d array. – Yue Jul 17 '17 at 16:02
  • @Yue In all the places you are trying to pass arrays, including LUsolve, yes – Caleth Jul 17 '17 at 16:02
  • @Yue that's not the whole error if the error contains candidate functions. – eerorika Jul 17 '17 at 16:04
  • @user2079303 "Candidate template ignored: could not match 'double' against 'double'" – Yue Jul 17 '17 at 16:13
  • @Yue that message seems nonsensical. Are you sure that there is no asterisks in there? Does the message mention which argument could not be matched? – eerorika Jul 17 '17 at 16:20
  • @user2079303 You mean no asterisks in my function implementation? No message for the where not matched? – Yue Jul 17 '17 at 16:33
  • @Yue I mean any asterisks in "could not match 'double' against 'double'". There is no reason for double to not match with double since they are exactly the same. It would make sense if one of them was double* for example. – eerorika Jul 17 '17 at 16:44
  • @user2079303 The header file is .h file and C header type. And the Cspline.c file is the place I used the LUsolve function. It is C++ Source type. Is that the problem? – Yue Jul 18 '17 at 04:43