1

I need to set a function pointer variable which is a method of a template class X to a method of X.

Here is a simple example.

X.h:

template<typename T>
class X {
public:
    typedef T (*valproc)(T v);

    X(T v);

    T add(T v);
    T val;
    valproc curproc;
};

X.cpp:

#include  "X.h"

template<typename T>
X<T>::X(T v) : val(v) {
    curproc = &X<T>::add;
}

template<typename T>
T X<T>::add(T v) {
    return v+val;
}

int main (int iArgC, char *apArgV[]) {
    X<int> *p = new X<int>(3);

    return  p->curproc(7);
}

When I compile this, I get an error:

$ g++ -c -g -Wall X.cpp
X.cpp: In instantiation of 'X<T>::X(T) [with T = int]':
X.cpp:15:29:   required from here
X.cpp:5:13: error: cannot convert 'int (X<int>::*)(int)' to 'X<int>::valproc {aka int (*)(int)}' in assignment
     curproc = &X<T>::add;

Apparently

int (X< int >::* )(int)
is not the same as
int (*)(int)

How can I define the correct type?

Teivaz
  • 5,462
  • 4
  • 37
  • 75
user1479670
  • 1,145
  • 3
  • 10
  • 22

4 Answers4

2

X<int>::add is a non-static member function. That means that &X<int>::add has the type int(X<int>::*)(int): pointer to non static member function of X<int> taking a single int parameter and returning int. Such a pointer cannot be converted to int(*)(int).

int(X<int>::*)(int) is conceptually more similar to int(*)(X<int>*, int) than it is to int(*)(int) (though the implementation may actually be much different depending on the platform's calling convention or if inheritance is involved). It requires an extra hidden X<int>* parameter: the this pointer.

The easiest way to do what you want would be to use a wrapper method:

template<typename T>
class X {
public:
    using valproc = T(X::*)(T v);

    X(T v)
        : val{v},
          proc{&X::add}
    {}

    T add(T v) { return v + val; }
    T curproc(T v) { return (this->*proc)(v); }

    T val;
    valproc proc;
};

Live Demo

The funky syntax (this->*proc)(i) says "call the member function pointed to by proc on the object pointed to by this with the parameter i".

Miles Budnek
  • 28,216
  • 2
  • 35
  • 52
1
#include <stdio.h>

template<typename T>
class X {
public:
    X(T v);
    T add(T v);
    T val;
    int (X::*curproc)(T v);
};

template<typename T>
X<T>::X(T v) : val(v) {
    curproc = &X<T>::add;
}

template<typename T>
T X<T>::add(T v) {
    return v+val;
}

int main()
{
    printf("Hello World\n");
    X<int> *p = new X<int>(3);

    printf("%d\n",  (p->*(p->curproc))(7));
}
0

Usualy template classes are defined in the header file. You can find more information here:

dimo raichev
  • 570
  • 5
  • 15
0

Change

return  p->curproc(7);

to

return (p->*(p->curproc))(7);

*(p->currproc) is the function pointer and that need to be called on p object pointer

For details

C++ function pointer (class member) to non-static member function

SaurabhS
  • 633
  • 1
  • 7
  • 18