Численные рецепты: как передать функцию в качестве аргумента функции newt в C++

Мой вопрос связан с числовыми рецептами. У меня есть глобальная функция, которая вычисляет вектор минимизируемых функций.

VecDoub vecfunc(VecDoub_I x) {
  // code is here
}

В функции класса run я попытался вызвать функцию числовых рецептов newt, которая считывает мою функцию vecfunc, как показано ниже:

class A {
    void run() {
        VecDoub_IO pt;
        pt.resize(2);
        pt[0] = 0.5;
        pt[1] = 0.5;
        bool check = false;
        newt<VecDoub>(pt, check, &vecfunc);
    }
}

Функция newt объявлена ​​как

template <class T>
void newt(VecDoub_IO &x, Bool &check, T &vecfunc)

Почему я получаю следующую ошибку компилятора?

error C2664: 'newt' : cannot convert parameter 3 from 'VecDoub (__cdecl *)(VecDoub_I)' to 'VecDoub &'

person Michael    schedule 19.10.2012    source источник
comment
InRe заглавный вопрос: есть способ c с указателями на функции, способ c++03 с функторами и способ c++11 с лямбда-выражениями. Я мог бы пройти через первые два, немного подумав и, может быть, методом проб и ошибок, но я надеюсь, что профессионал сравнит и сопоставит все три...   -  person dmckee --- ex-moderator kitten    schedule 19.10.2012


Ответы (2)


При вызове newt вы явно указываете, что T является VecDoub (вы указали newt<VecDoub>), но вы передаете ему адрес функции, поэтому компилятор не может преобразовать вашу функцию в VecDoub&. Если вы хотите VecDoub& в newt, тогда вызовите vectfunc и сохраните его во временной переменной, а затем передайте эту переменную функции (поскольку в newt последний параметр является ссылкой на T), но если вам действительно нужна функция в newt, то зачем вы пишете newt<VecDoub>(pt, check, &vecfunc) в то время как вы можете написать newt(pt, check, &vecfunc) и позволить C++ вывести тип за вас? кроме того, чтобы получить функции в newt, не получайте их по ссылке, а получайте их по значению, поэтому newt должен быть объявлен как:

template <class T>
void newt(VecDoub_IO &x, Bool &check, T vecfunc)

Поскольку функции обычно представляют собой небольшие объекты или указатели, это будет работать и не снизит производительность.

person BigBoss    schedule 19.10.2012

Потому что вы должны вызывать функцию и передавать возвращаемое значение в качестве параметра, а не саму функцию.

newt<const VecDoub>(pt, check, vecfunc(something) );

Я добавил const, потому что ссылка должна быть постоянной, иначе возвращаемое значение из vecfunc не может быть привязано к ней, потому что это временное значение.

Объяснить:

newt<VecDoub>(pt, check, &vecfunc);

пытается вызвать функцию, аналогичную

newt_VecDoub(VecDoub_IO &x, Bool &check, VecDoub &vecfunc);

Третий параметр, который вы пытаетесь передать, это &vecfunc, который имеет тип VecDoub (__cdecl *)(VecDoub_I), так что он, очевидно, не может работать.

person Luchian Grigore    schedule 19.10.2012