‹неразрешенный тип перегруженной функции› при попытке передать метод агрегированного объекта методу его класса

У меня возникла проблема с компиляцией моего кода. У меня есть следующая структура:

#include <cstdlib>

using namespace std;

typedef double (*FuncType)(int );

class AnotherClass {
   public:
          AnotherClass() {};       
   double funcAnother(int i) {return i*1.0;}
};

class MyClass {
public:
         MyClass(AnotherClass & obj) { obj_ = &obj;};
    void compute(FuncType foo);
    void run();

    protected:
      AnotherClass * obj_;   /*pointer to obj. of another class */   
};

void MyClass::compute(FuncType foo) 
{
    int a=1;
    double b;
    b= foo(a);    
}

void MyClass::run()
{
     compute(obj_->funcAnother);
}

/*
 * 
 */
int main(int argc, char** argv) {
    AnotherClass a;
    MyClass b(a);
    b.run();    

    return 0;
}

При попытке скомпилировать выдает:

main.cpp:39:31: error: no matching function for call to ‘MyClass::compute(<unresolved overloaded function type>)’
main.cpp:30:6: note: candidate is: void MyClass::compute(double (*)(int))

Что здесь не так?

p/s/ AnotherClass * obj_; должно оставаться так, потому что я пишу какую-то функцию в большую библиотеку и не могу ее изменить.

-------------- рабочая версия Бенджамина -------

#include <cstdlib>

using namespace std;


class AnotherClass {
   public:
          AnotherClass() {};       
   double funcAnother(int i) {return i*1.0;}
};


struct Foo
{

    /*constructor*/
    Foo(AnotherClass & a) : a_(a) {};

    double operator()(int i) const
    {
        return a_.funcAnother(i);
    }          

    AnotherClass & a_;               
};


class MyClass {
public:
         MyClass(AnotherClass & obj) { obj_ = &obj;};

    template<typename FuncType>     
    void compute(FuncType foo);
    void run();

   protected:
      AnotherClass * obj_;   /*pointer to obj. of another class */   
};

template<typename FuncType>
void MyClass::compute(FuncType foo) 
{
    int a=1;
    double b;
    b= foo(a);    
}

void MyClass::run()
{
    Foo f(*obj_);
    compute(f);
}

/*
 * 
 */
int main(int argc, char** argv) {
    AnotherClass a;
    MyClass b(a);
    b.run();    

    return 0;
}

Всем большое спасибо за помощь!


person Denis    schedule 10.08.2011    source источник
comment
Пожалуйста, опубликуйте минимальный оскорбительный пример. Ошибка не вызвана кодом, который вы нам показываете.   -  person Alexandre C.    schedule 10.08.2011
comment
Пожалуйста, публикуйте настоящий код (сократите до минимального примера), а не псевдокод.   -  person Kerrek SB    schedule 10.08.2011
comment
Похоже, вы объявили funcAnother функцией-членом. Если вы сделаете это функцией класса static, она должна работать. Конечно, если он ссылается, это не сработает, и вам нужен другой подход.   -  person user786653    schedule 10.08.2011
comment
Воспроизведите проблему в минимальной программе, а затем опубликуйте полный реальный код.   -  person Cheers and hth. - Alf    schedule 10.08.2011
comment
нет членской функции void run() в группе class MyClass. Также AnotherClass должен быть определен (или, по крайней мере, предварительно объявлен) до MyClass   -  person A. K.    schedule 10.08.2011
comment
хорошо, переписал его в небольшую программу, и ошибка точно такая же.   -  person Denis    schedule 10.08.2011


Ответы (2)


Следующий класс функций будет соответствовать сигнатуре вашего FuncType:

struct Foo
{
    AnotherClass & a_;
    Foo(AnotherClass & a) a_(a) {}

    double operator()(int i) const
    {
        return a_.funcAnother(i);
    }
};

Измените MyClass::compute на шаблон, таким образом:

template<typename FuncType>
void MyClass::compute(FuncType foo) 
{
    int a=1;
    foo(a);
}

Затем вы можете вызвать run следующим образом:

void MyClass::run()
{
    compute(Foo(*obj_));
}

Если ваш компилятор поддерживает лямбда-выражения (а это, скорее всего, так и есть), вы можете отказаться от класса функции и просто определить run следующим образом:

void MyClass::run()
{
    auto f = [this](int i) {
        return obj_->funcAnother(i);
    };

    compute(f);
}
person Benjamin Lindley    schedule 10.08.2011

С,

funcAnother(int i);

является функцией-членом, она передает неявный this, а затем прототип не соответствует типу вашего указателя на функцию.

Typedef для указателя на функцию-член должен быть:

typedef double (AnotherClass::*funcPtr)(int);

Здесь представлена ​​модифицированная компилируемая версия вашего кода. Пожалуйста, проверьте встроенные комментарии, чтобы понять изменения. Также я не учел другие детали, вы можете добавить их.

person Alok Save    schedule 10.08.2011
comment
Итак, как мне изменить свой указатель, чтобы он соответствовал функции, которую я хочу вызвать? - person Denis; 10.08.2011
comment
Вероятно, это не ошибка (но тем не менее это ошибка с предоставленным кодом). Ошибка возникает из-за попытки присвоить имя перегруженной функции указателю на функцию. - person Alexandre C.; 10.08.2011
comment
@Денис: обновил ответ. Вам необходимо сделать следующее: 1. Опубликовать фактический образец кода, 2. Опубликовать полный образец. Приведенное выше обновление устраняет одну из обнаруженных ошибок. в вашем коде, это не решает ошибку, которую вы опубликовали. Вероятно, это потому, что у вас есть неоднозначные перегруженные функции внутри вашего класса, и вы пытаетесь их использовать. - person Alok Save; 10.08.2011
comment
Я обновил код. Также попробовал ваше решение, но оно не решает проблему, все еще есть ошибка «неразрешенная перегруженная функция». - person Denis; 10.08.2011
comment
@Denis: обновил ответ. Перейдите по ссылке, чтобы получить компилируемую версию вашего кода. - person Alok Save; 10.08.2011
comment
Однако ваша версия на самом деле не вызывает функцию. Для этого вам нужно передать ссылку на фактический объект. - person Benjamin Lindley; 10.08.2011
comment
@Als, я проверил ваше исправление, оно компилируется, но как мне запустить функцию foo внутри «compute»? Я попробовал «двойное разрешение = foo (a);» Но это не работает; - person Denis; 10.08.2011
comment
@Benjamin Lindley Действительно, вы правы, функция не вызывается. Но я не понимаю, почему объект инициализируется, так по какой причине функция .run не вызывается? Я попытался инициализировать MyClass с помощью «MyClass (AnotherClass * obj) {obj_ = obj;};» но я все еще не выполнил запуск. - person Denis; 10.08.2011
comment
@Denis: вызывается run, и внутри него вызывается compute, но funcAnother не является и не может быть без объекта AnotherClass, на который можно воздействовать. - person Benjamin Lindley; 11.08.2011
comment
@Benjamin, но у меня есть «AnotherClass a; MyClass b(a);', так что этот объект есть. И я просто отладил его, и вызывается funcAnother. - person Denis; 11.08.2011
comment
@Benjamin (я говорю о версии функторов, а не указателях на функции). Я только что понял, что вы, должно быть, говорите об исправлении Алса? - person Denis; 11.08.2011
comment
Alok, есть ли способ определить шаблонную версию функций, принимающих аргументы, которые являются функциями-членами, чтобы она автоматически выводила AnotherClass::? - person woosah; 28.03.2013