functors-binders: посоветуйте элегантное решение, плз.
От: stbzh  
Дата: 28.07.11 10:19
Оценка:
Не могу сообразить, как лучше поступить в такой ситуевине: необходимо передавать в обычную функцию функторы, принимающие разное количество параметров. Раньше у меня все это было на указателях на функции, где не совсем красиво неиспользовались дополнительные параметры. Вот и было принято решение использовать функторы. И вот тут я чего то никак не могу сообразить, можно ли передавать в обычную функцию нечто вроде указателя на метод класса, и использовать затем в этом месте функтор через биндер. Сейчас все это дело по вполне понятным причинам не работает, и заставить это работать, не прибегая к виртуальным функциям, я пока не пойму как... Вобщем все станет ясно из кода, который можно также посмотреть здесь http://codepad.org/1YHZDKAC
Собственно код:
#include<iostream>
#include<string>

struct two_operand_fn
{
  void operator()(const std::string& str, size_t len) const
  {
    std::cout << "two_operand_fn: " << str << "; " << len << std::endl;
  }
};

struct four_operand_fn
{
  void operator()(const std::string& str, size_t len, char ch, double d) const
  {
    std::cout << "four_operand_fn: " << str << "; " << len << "; " << ch << "; " << d << std::endl;
  }
};

struct four_binder: public two_operand_fn
{
  const four_operand_fn& op_;
  char ch_;
  double d_;

  four_binder(const four_operand_fn& op, char ch, double d)
  : op_(op), ch_(ch), d_(d)
  {}

  void operator()(const std::string& str, size_t len) const
  {
    op_(str, len, ch_, d_);
  }
};

four_binder bind_four(const four_operand_fn& op, char ch, double d)
{
  return four_binder(op, ch, d);
}

void foo(const std::string& msg, const two_operand_fn& fn)
{
  std::cout << msg;
  std::string str("Hello");
  size_t len(123);
  fn(str, len);
}

int main()
{
  foo("It's an obvious two argument call: ", two_operand_fn());

  char ch('A');
  double d(1.23);
  foo("Would like to call a four argument functor: ", bind_four(four_operand_fn(), ch, d));

  return 0;
}
functor binder
Re: functors-binders: посоветуйте элегантное решение, плз.
От: stbzh  
Дата: 28.07.11 11:35
Оценка:
Было бы здорово заставить работать что то вроде следующего:
#include<iostream>
#include<string>

struct two_operand
{
  void fn(const std::string& str, size_t len) const
  {
    std::cout << "two_operand::fn: " << str << "; " << len << std::endl;
  }
};

struct four_operand: public two_operand
{
  char ch_; double d_;

  four_operand(char ch, double d): ch_(ch), d_(d) {}

  void fn(const std::string& str, size_t len) const
  {
    std::cout << "four_operand::fn: " << str << "; " << len << "; " << ch_ << "; " << d_ << std::endl;
  }
};

typedef void (two_operand::*pf)(const std::string&, size_t) const;

void foo(const std::string& msg, const two_operand& obj, pf func)
{
  std::cout << msg;
  std::string str("Hello");
  size_t len(123);
  obj.*func(str, len);
}

int main()
{
  foo("It's an obvious two argument call: ", two_operand(), two_operand::fn);

  char ch('A');
  double d(1.23);
  foo("Would like to call a four argument functor: ", four_operand(ch, d), four_operand::fn);

  return 0;
}


Только еще и с возвращением указателя на функцию самим функтором, что то типа такой бредятины (чтобы избавиться от передачи и самого объекта и указателя на его функцию-член):
struct two_operand
{
  typedef void (two_operand::*pf)(const std::string&, size_t) const;
  pf operator()() { return &(this->fn) }

  void fn(const std::string& str, size_t len) const
  {
    std::cout << "two_operand::fn: " << str << "; " << len << std::endl;
  }
};
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.