Как определить и установить указатель функции на метод класса шаблона - PullRequest
0 голосов
/ 13 июня 2018

Мне нужно установить переменную указателя функции, которая является методом класса шаблона X, на метод X.

Вот простой пример.

Xh :

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);
}

Когда я скомпилирую это, я получаю ошибку:

$ 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;

Видимо

int (X< int >::* )(int)
отличается от
int (*)(int)

Как определить правильный тип?

Ответы [ 4 ]

0 голосов
/ 13 июня 2018

Изменить

return  p->curproc(7);

на

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

* (p-> currproc) - указатель функции, который необходимо вызывать для указателя объекта p

Подробнее

Указатель функции C ++ (член класса) на нестатическую функцию-член

0 голосов
/ 13 июня 2018

X<int>::add является нестатической функцией-членом.Это означает, что &X<int>::add имеет тип int(X<int>::*)(int): указатель на нестатическую функцию-член X<int>, принимающий единственный параметр int и возвращающий int.Такой указатель не может быть преобразован в int(*)(int).

int(X<int>::*)(int) концептуально больше похож на int(*)(X<int>*, int), чем на int(*)(int) (хотя реализация может фактически сильно отличаться в зависимости от соглашения о вызовах платформыили если наследование задействовано ).Для этого требуется дополнительный скрытый параметр X<int>*: указатель this.

Самый простой способ сделать то, что вы хотите, - использовать метод-обертку:

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;
};

Демонстрационная версия

Причудливый синтаксис (this->*proc)(i) гласит: «вызвать функцию-член, указанную proc, для объекта, на который указывает this, с параметром i".

0 голосов
/ 13 июня 2018
#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));
}
...