mem_func и виртуальная функция - PullRequest
       4

mem_func и виртуальная функция

2 голосов
/ 23 декабря 2010

У меня есть следующие классы:

 class A
{
   public:
        virtual void myfunc(unsigned char c, std::string* dest) = 0;
};

   class B : public class A
{
    public:
        virtual void myfunc(unsigned char c, std::string* dest);
};

void someOtherFunc(const std::string& str,A *pointerFunc)
{
    std::string tmp;
        for_each(str.begin(),
                 str.end(),                 
                 std::bind2nd(std::mem_fun(pointerFunc->myfunc), &tmp));
}

Я получаю следующую ошибку компиляции: ошибка: нет соответствующей функции для вызова \ u2018mem_fun () \ u2019

Ты знаешь почему?

Ответы [ 4 ]

1 голос
/ 23 декабря 2010

Вы ищете std::mem_fun(&A::myfunc).

РЕДАКТИРОВАТЬ: Вы не можете использовать mem_fun здесь вообще - никакая перегрузка mem_fun не позволяет вам сделатьфункция-член с двумя аргументами в функторе.Вам нужно будет использовать что-то вроде boost::bind / std::tr1::bind (если у вас TR1) / std::bind (если у вас C ++ 0x) или вам придется написать свой собственный функтор.

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

У вас есть несколько способов обойти это:

  1. Напишите свой собственный функтор, который делает то, что вы хотите.
  2. Напишите явный циклвместо std::for_each.
  3. Одна из еще не стандартных функций связывания, которые я упоминал выше (и продемонстрировал в ответе Дэвида)
  4. Не беспокойтесь о виртуальной функции в первойplace - заставляет ваш метод принимать простой указатель на функцию и реализовывать его в терминах указателя на функцию.Конечно, это работает только в том случае, если myfunc не зависит от членов класса, к которому он принадлежит (в этом случае его вообще не следовало помещать в класс)
0 голосов
/ 23 декабря 2010

Глядя на реализацию, стоящую за std :: mem_fun, вы сможете написать свои собственные:

РЕДАКТИРОВАТЬ (сделал его "читабельным для человека")

template<class Result, class Ty, class Arg>
class mem_fun1_t : public binary_function<Ty*, Arg, Result>
{
private:
 Result (Ty::*m_mf)(Arg);

public:
 mem_fun1_t(Result (Ty::*mf)(Arg)) : m_mf(mf) { }

 Result operator()(Ty* pLeft, Arg Right) const {
  return ((pLleft->*m_mf)(Right));
 }
};
0 голосов
/ 23 декабря 2010

Ваша декларация не соответствует тому, что вы хотите сделать.

попробовать:

void someOtherFunc(const std::string& str)
{
    std::string tmp;

    B BInstance;
    A* ptrToB = &BInstance;


    for_each(str.begin(),
        str.end(),                 
        boost::bind(&A::myfunc, ptrToB, _1, &tmp));
}

это (или вариант) должно делать то, что вы хотите.

0 голосов
/ 23 декабря 2010

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

...