Hi I'm doing a templated matrix class,
and I'd like to be able to pass a function pointer to a function that uses the rows.

template<typename T>
T sum(Array<T> &a){ // a simple function that return the sum of an Array
  T res=0;
  for(int i=0;i<a.length();i++)
    res+=a(i);
  return res;
}

template<typename T>
Array<T> getrow(Matrix<T> &m,int r){// a simple function that return a row from a matrix
  Array<T> retAry(m.y());
  for(int i=0;i<m.y();i++)
    retAry(i) = m(r,i);
  return retAry;
}


//this is the function I'd like to implement
template<typename T>
Array<T> apply(Matrix<T> &m,T (*fun)(Array<T>)){
  Array<T> retA(m.x());
  for (int i=0;i<m.x();i++){
    Array<T> r = getrow(m,i);
    retA(i) = (*fun)(r);
  } 
  return  retA;
}

//same as above but with out the function pointer
template<typename T>
Array<T> applyThisWorks(Matrix<T> &m){
  Array<T> retA(m.x());
  for (int i=0;i<m.x();i++){
    Array<T> r = getrow(m,i);
    retA(i) = sum(r);
  } 
  return  retA;
}


int main(){
  Matrix<int> m(3,5);
  fillIt(m);
  m.print();
  Array<int> var = applyThisWorks(m);
  //Array<int> var = apply(m,&sum);//how do I call the function?
  
  cout <<"this is the rowwise sum:"<<var;
}

My code is of cause a lot more, I can post it,
if you need it.
Everything is working, and when I use the nonfunction pointer I get the desired output.

dim is: (3,5)
0 1 2 3 4 
5 6 7 8 9 
10 11 12 13 14 
this is the rowwise sum:10 35 60

But If I try to compile the desired general version i get this error

matrix.cpp: In function ‘int main()’:
matrix.cpp:230: error: no matching function for call to ‘apply(Matrix<int>&,
<unresolved overloaded function type>)’
matrix.cpp:206: note: candidates are: Array<U> apply(Matrix<T>&, T (*)(Array<U>))
[with T = int]

Is there someway I can coerce the function type,
or is it even possible to do this?

thanks in advance

Recommended Answers

All 3 Replies

There are two problems. First, you can't provide a pointer to a template, it has to be a pointer to an instantiation of the template. Translation: provide the template arguments:

Array<int> var = apply ( m, &sum<int> );

The second problem is that there's a mismatch between the function signature apply expects and the signature of the function you're actually passing. Specifically, the former doesn't take a reference as the parameter and the latter does. Fix your definition of apply such that fun takes a reference to Array<T>:

template<typename T>
Array<T> apply(Matrix<T> &m,T (*fun)(Array<T>&)){
  return Array<T>();
}

Well You should first implement a template with member function declarations and then you can

T& Array<T>:: applyThisWorks(Matrix<T> &m){
  Array<T> retA(m.x());
  for (int i=0;i<m.x();i++){
    Array<T> r = getrow(m,i);
    retA(i) = sum(r);
  } 
  return  retA;
}

I am not a expert on this as i am still learning templates myself . But i think this is the way to do it.

Thanks Narue,
it works perfectly now.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.