tags:

views:

136

answers:

6

I have trouble compiling a class, which has function pointers as member variables. The pointers are to functions which take an instance of a class as argument.

Like

template<class T, int N>
double (*f)(Vector<T,N> v);

I get "error: data member 'f' cannot be a member template" Compiler is gcc 4.2.

Edit

Before using templates I just had

double (*f)(Vector v);

This also works

double (*f)(Vector<double,2> v)

But I would like to have a function pointer for a function which takes a generic Vector as argument..

A: 

Well, the compiler doesn't know at the compile time, how many f's are you going to have (one for each possible T and N?). Therefore the compiler cannot calculate how much memory do objects of your class need. That's why such constructs are prohibited.

Vlad
A: 

You can't have a templated pointer to function, that makes no sense. But what you can do is

#include <vector>

template <typename T>
void foo(const std::vector<T>& v) {
   // do something
}

void (*ptr_foo)(const std::vector<int>&) = &foo<int>;

(here the function pointers a templated function, which template argument is explicitly set to int)

Kotti
+1  A: 

That isn't quite valid c++, basically what you're looking for are template-template parameters.

http://www.progdoc.de/papers/ttp/psi-ttp/psi-ttp.html explains all about them

Generally, if you get yourself into this situation, you want to find a workaroumd, because your code becomes illegible VERY quickly

Ryan Rohrer
A: 

Because your code makes just as much sense as:



struct X
{
  template < typename T >
  std::vector<T> vect;
};

You're trying to make a member variable a template. This is just not a valid C++ construct and I seriously doubt it ever will be.

How do you do what you actually want? I'm not sure since I don't know what you actually are trying to accomplish and why.

Noah Roberts
+2  A: 

Use a member typedef:

template <typename T, int N>
class Vector
{
public:

    /// type of function pointer
    typedef double (*FuncPtr)( const Vector& );

};

// concrete type
typedef Vector<double,10> VecDouble10;

// actual function
double func( const VecDouble10>& );

// usage
VecDouble10::FuncPtr fp = func;
Nikolai N Fetissov
I don't understand the first typedef, what would be the alias name for the function pointer?
Nils
Could you explain your answer a bit more, why should it work with typedef if it does not without it?
Nils
Nikolai N Fetissov
Nils
Because it's within the template definition - template parameters are assumed.
Nikolai N Fetissov
+1  A: 

If you want to have a "template pointer", you could try a function object. The example below adds 1.0 to the wrapped function template.

struct AcceptsVector {
  template<typename T, int N>
  double operator()(Vector<T,N> v) const { return 1.0 + real_f(v); }
};

AcceptsVector f;

The difference to a "real" template pointer is that you cannot re-seat "AcceptsVector" to call another template, like you can do with normal function pointers. The binding is hardcoded at compile-time. However you can pass along f like a function pointer, and can call f with any Vector<T, N> like a template.

Johannes Schaub - litb