Указатели на функции и шаблоны C ++ - PullRequest
3 голосов
/ 08 декабря 2011

У меня есть код C ++, и мне действительно нужно использовать функцию C:

int procedure(... , S_fp fun , ...)

где fun - указатель на функцию, сигнатура которой должна быть такой:

int fun(double* , double* , double)

Функция, указатель на которую я хочу использовать, является членом шаблона класса:

template<int nPar> class PenaltyAlgorithm
{
public:
...
int Calculate(double* param, double* val, double prec)
{
   ...
}
...
}

Как видите, ее подпись в порядке.Но когда я делаю это: процедура (... & PenaltyAlgorithm :: Calculate, ...);

Я получаю ошибку:

error: cannot convert ‘int (PenaltyAlgorithm<30>::*)(double*, double*, double)’ to ‘int (*)(...)’ for argument ...

Пожалуйста, помогите.Если вам нужна дополнительная информация, пожалуйста, напишите.

Спасибо !!!

Прочитав ответы, я понял, что важно добавить информацию о классе:

template<int nPar> class PenaltyAlgorithm
{
public:
int Calculate(double* param, double* val, double prec)
    {
    *val = comp_fun->Compute(param);
    }

double* RunAlgorithm()
    {
        ...
        procedure(... &PenaltyAlgorithm<nPar>::Calculate, ...);
        ... 
    }
...
private:
...
CompositeFunction<nPar>* comp_fun;
}

1).Я не могу использовать статическое веселье, потому что этому веселью нужно получить доступ к членам класса;

2).Можем ли мы использовать тот факт, что мы вызываем «процедуру» от забавного члена класса?

Ответы [ 5 ]

3 голосов
/ 08 декабря 2011

Рассчитать это нестатический метод на PenaltyAlgorithm. Для этого требуется экземпляр PenaltyAlgorithm, поэтому его нельзя передать функции C в виде простого указателя на функцию.

Может ли функция Calculate стать статической? Если это возможно, он должен работать так же, как указатель функции C, только он не сможет получить доступ к нестатическим данным в классе PenaltyAlgorithm.

1 голос
/ 09 декабря 2011

Если int procedure(... , S_fp fun , ...) обязательно должна быть функцией C, то нет способа сделать то, что вы ищете напрямую.Если вы попытаетесь передать указатель на функцию-член класса, он будет скрывать этот указатель в качестве первого аргумента в стеке, поэтому прототипы не будут совпадать.

Однако вы можете создать глобальную или статическую функцию, которая внутреннеиспользует сохраненный указатель экземпляра для косвенного доступа к классу PenaltyAlgorithm.Вы можете попробовать следующее:

1) Сохранить указатель экземпляра класса, который вы хотите передать в функцию procedure, в глобальную переменную.

2) Создать новую глобальную функцию int CalculateGlobal(double* param, double* val, double prec)

3) Передать указатель функции CalculateGlobal в качестве указателя на функцию procedure.

4) Функция CalculateGlobal может затем использовать сохраненный указатель экземпляра для доступа к определенному классувнутренние органы.

Ну, конечно, это не очень хороший способ делать вещи ...

1 голос
/ 08 декабря 2011

Помните, что int Calculate(double* param, double* val, double prec) в качестве члена экземпляра имеет скрытый указатель this, который не будет иметь глобальная функция или статический член.Без этого он не будет знать, на каком PenaltyAlgorithm его запустить.

Либо указатель должен быть типа int (PenaltyAlgorithm::*)(double* param, double* val, double prec), либо Calculate должен быть статическим.

0 голосов
/ 08 декабря 2011

Вы должны сделать Calculate статическим, использовать

static int Calculate(double* param, double* val, double prec)

вместо

int Calculate(double* param, double* val, double prec)
0 голосов
/ 08 декабря 2011

Вы не можете передать такой указатель функции-члену, если она не является статической функцией-членом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...