Я пытаюсь использовать алгоритм stl for_each, не увеличивая количество шаблонов в моем коде. std :: for_each хочет создать экземпляр класса MyFunctor по значению, но не может, поскольку его абстрактный. Я создал класс адаптера функтора, который передает указатель, а затем разыменовывает его, когда это необходимо.
Мой вопрос:
У STL или Boost уже есть такой класс адаптера? Я не хочу изобретать велосипед!
struct MyFunctor {
virtual ~MyFunctor() {}
virtual void operator()(int a) = 0;
}
namespace {
template<typename FunctorType, typename OperandType> struct
FunctorAdapter
{
FunctorAdapter(FunctorType* functor) : mFunctor(functor) {}
void operator()(OperandType& subject)
{
(*mFunctor)(subject);
}
FunctorType* mFunctor;
}; }
void applyToAll(MyFunctor &f) {
FunctorHelper<MyFunctor, int> tmp(&f);
std::for_each(myvector.begin(), myvector.end(), tmp); }
Ваше здоровье,
Дэйв





Вы можете использовать функциональные адаптеры (и их прокладки) от functional.
#include <functional>
using namespace std;
for_each( vec.begin(), vec.end(), :mem_fun_ptr( &MyClass::f ) );
Если ваш контейнер содержит указатели на объекты, используйте mem_fun_ptr, иначе используйте mem_fun. Рядом с ними есть оболочки для функций-членов, которые принимают 1 аргумент: mem_fun1_ptr и mem_fun1.
@Evan: действительно, вы можете вызвать функцию-член с одним и тем же аргументом для каждого объекта. Первый аргумент оболочек mem_fun1 - это указатель this, второй - аргумент функции-члена:
for_each( vec.begin(), vec.end(), bind2nd( mem_fun_ptr( &MyClass::f ), 1 ) );
С большим количеством аргументов становится более читаемым создание цикла самостоятельно или создание пользовательского функтора, который имеет константные переменные-члены, представляющие аргументы.
Нет, потому что указатель this будет передан в качестве аргумента функцией for_each. Указатели функций-членов будут обрабатывать виртуальный поиск.
Не могу понять, почему у него больше голосов, чем за правильный ответ; он не работает с объектами-функторами согласно запросу.
Как насчет того, чтобы забыть обо всех обертках указателя функтора и вместо этого использовать
bind(functor_pointer,mem_fun1(&MyFunctor::operator());
как функтор? Таким образом, вам не нужно беспокоиться об управлении копией в любой форме или форме.
почему бы не использовать BOOST_FOREACH?
Похоже, вы могли бы извлечь выгоду из Boost :: Function.
Если я правильно помню, это тоже библиотека только для заголовков, так что с ней легко работать.
Основываясь на ответе @xtofl, поскольку массив содержит указатели int, а не this, я думаю, что правильное заклинание
class MyClass
{
virtual void process(int number) = 0;
};
MyClass *instance = ...;
for_each( vec.begin(), vec.end(), binder1st(instance, mem_fun_ptr(&MyClass::process) );
Единственное отличие от кода @ xtofl - это binder1st, а не binder2nd. binder2nd позволяет передавать одно и то же число различным указателям «this». binder1st позволяет передавать различные числа в один указатель this.
Здесь вам может помочь tr1 :: ref - он предназначен для использования в качестве справочной оболочки, чтобы вы могли передавать обычные объекты по ссылке в объекты привязки или функции (даже абстрактные) по ссылкам на стандартные алгоритмы.
// requires TR1 support from your compiler / standard library implementation
#include <functional>
void applyToAll(MyFunctor &f) {
std::for_each(
myvector.begin(),
myvector.end(),
std::tr1::ref(f)
);
}
Однако ЗАМЕТЬТЕ, что компиляторы без поддержки decltype МАЙ отклоняют передачу ссылки на абстрактный тип ... поэтому этот код может не компилироваться, пока вы не получите поддержку C++ 0x.
Похоже, я реализовал в FunctorAdapter нечто очень похожее на reference_wrapper, которое возвращает tr1 :: ref.
хороший ответ, мне неясно из его примера, но если вектор содержит целые числа, разве ему также не нужно привязать «этот указатель» к этому mem_fun?