Pergunta

Eu estou tentando usar STL algoritmo for_each sem proliferando modelos em todo o meu código. std :: for_each quer classe MyFunctor instanciar por valor, mas não pode desde o seu resumo. Eu criei uma classe do adaptador functor que passa um ponteiro ao redor e então derefernces-lo quando necessário.

Minha pergunta:

Será que o STL ou aumentar já tem uma tal classe do adaptador? Eu não quero ter que reinventar a roda!

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

Cheers,

Dave

Foi útil?

Solução

tr1 :: ref pode ajudá-lo aqui --- que está destinado a ser um invólucro de referência para que você possa passar objetos normais por referência para ligar ou função objetos (mesmo os abstratos) por referência aos algoritmos padrão.

// 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) 
    ); 
}

No entanto, note que compiladores sem apoio decltype pode Rejeitar passando uma referência a um tipo abstrato ... então este código pode não ser compilado até obter suporte C ++ 0x.

Outras dicas

Você pode usar os adaptadores de função (e seus calços) a partir functional.

#include <functional>

using namespace std;
for_each( vec.begin(), vec.end(), :mem_fun_ptr( &MyClass::f ) );

Se o seu recipiente contém ponteiros-a-objetos, uso mem_fun_ptr, uso mem_fun mais. Ao lado destes, existem wrappers para funções membro que levam um argumento: mem_fun1_ptr e mem_fun1

.

@Evan: na verdade, você poderia chamar a função de membro com o mesmo argumento para cada objeto. O primeiro argumento dos invólucros mem_fun1 é o ponteiro this, o segundo é o argumento da função membro:

for_each( vec.begin(), vec.end(), bind2nd( mem_fun_ptr( &MyClass::f ), 1 ) );

Com mais argumentos, torna-se mais legível para criar um loop de si mesmo, ou criar um functor personalizado que tem variáveis ??de membro const que representam os argumentos.

Parece que você poderia beneficiar boost :: Função .

Se bem me lembro, é um cabeçalho única biblioteca também, por isso é fácil de ir buscá-la com ele.

E sobre esquecendo todo o embrulho do ponteiro functor e, em vez uso bind(functor_pointer,mem_fun1(&MyFunctor::operator()); como o functor? Dessa forma, você não precisa se preocupar em gerenciar a cópia em qualquer forma ou meio.

Com base na resposta de @ xtofl, já que a matriz contém int do e não "este" ponteiros, eu acho que o encantamento correto é

class MyClass
{
  virtual void process(int number) = 0;
};
MyClass *instance = ...;

for_each( vec.begin(), vec.end(), binder1st(instance, mem_fun_ptr(&MyClass::process) );

A única diferença em relação de @ xtofl código é binder1st em vez de binder2nd. binder2nd permite que você passe teh mesmo número a várias "este" ponteiros. binder1st permite passar vários números a um ponteiro "este".

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top