Не могу сообразить, как лучше поступить в такой ситуевине: необходимо передавать в обычную функцию функторы, принимающие разное количество параметров. Раньше у меня все это было на указателях на функции, где не совсем красиво неиспользовались дополнительные параметры. Вот и было принято решение использовать функторы. И вот тут я чего то никак не могу сообразить, можно ли передавать в обычную функцию нечто вроде указателя на метод класса, и использовать затем в этом месте функтор через биндер. Сейчас все это дело по вполне понятным причинам не работает, и заставить это работать,
не прибегая к виртуальным функциям, я пока не пойму как... Вобщем все станет ясно из кода, который можно также посмотреть здесь
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;
}
Было бы здорово заставить работать что то вроде следующего:
#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;
}
};