<неразрешенный тип перегруженной функции> при попытке передать метод агрегированного объекта его методу класса - PullRequest
2 голосов
/ 10 августа 2011

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

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

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

Ответы [ 2 ]

3 голосов
/ 10 августа 2011

Поскольку

funcAnother(int i);

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

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

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

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

1 голос
/ 10 августа 2011

Следующий класс функций будет соответствовать сигнатуре вашего 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 какthis:

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

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

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

    compute(f);
}
...