Pergunta

Eu tenho uma classe de functor abstrata que sobrecarrega o operador () e objetos derivados que a implementam.

Eu tenho uma função (parte de outra classe) que tenta fazer uma variedade dessas classes de functor e tenta passar um ponteiro para uma função de membro para o algoritmo STD para_each (), aqui está uma visão geral do que estou fazendo:

EDIT: Eu o limpei e coloquei o pequeno exemplo antigo para maior clareza.

class A{
  operator()(x param)=0;
  operator()(y param)=0;
}

class B: public A{
  operator()(x param); //implemented
  operator()(y param);
}
...// and other derived classes from A

void ClassXYZ::function(A** aArr, size_t aSize)
{
  ...//some code here

  for(size_t i = 0; i< aSize; i++){

    A* x = aArr[i];
    for(v.begin(), v.end(), ...//need to pass pointer/functor to right operator() of x here

..//other code
}

Eu tentei algumas maneiras e não consigo descobrir como fazê -lo funcionar, preciso usar o tipo abstrato, pois poderia ter diferentes tipos derivados, mas todos terão que implementar o mesmo operador () (Param X ) função.

Eu só preciso da função for_each () para poder chamar o operador de função do membro () (param x). Eu tenho uma função diferente na qual ela tem implementações concretas e simplesmente passa uma instância delas e funciona. Estou tentando obter um efeito semelhante aqui, mas sem o conhecimento de quais classes concretas recebem.

O que estou fazendo errado?

Foi útil?

Solução

Se eu entendi o que você quer fazer, existem alguns erros no seu snippet de código:

  • sizeof aArr está errado, você precisa passar o tamanho explicitamente (notado por Chrisw)
  • Ausência de virtual especificador na declaração original de operator()()
  • Não tenho certeza de onde seu for o loop termina como não há correspondência } (Eu suspeito que não deveria estar lá)

Aqui está algum código que percorre uma matriz de A (ou A-Derived) Objetos e chamados operator() em cada um, passando por um argumento aprovado como o param parâmetro:

#include <iostream>
#include <algorithm>
#include <functional>

using namespace std;

typedef double param;      // Just for concreteness

class A {
public:
    virtual void operator()(param x) = 0;
};

class B : public A {
public:
    void operator()(param x) { cerr << "This is a B!  x==" << x << ".\n"; }
};

void function(A** aArr, size_t n, param theParam) {
    void (A::*sFunc)(param x) = &A::operator();
    for_each(aArr, aArr + n, bind2nd(mem_fun(sFunc), theParam));
}

int main(int argc, char** argv) {
    A* arr[] = { new B(), new B(), new B() };

    function(arr, 3, 42.69);

    delete arr[0];
    delete arr[1];
    delete arr[2];
    return 0;
}

mem_fun() é necessário para converter um ponteiro de função de membro de 1 parâmetro em um objeto de função de 2 parâmetros; bind2nd() então produz a partir desse objeto de função de 1 parâmetro que corrige o argumento fornecido a function() Como o segundo argumento. (for_each() requer um ponteiro de função ou objeto de função de 1 parâmetro.)

EDITAR: Baseado em Resposta de Alex Tingle, Deduzir que você pode ter desejado function() fazer muitas coisas em um único A-Objeto derivado. Nesse caso, você vai querer algo como:

void function(A** aArr, size_t n, vector<param> const& params) {
    for (size_t i = 0; i < n; ++i) {
        void (A::*sFunc)(param x) = &A::operator();
        for_each(params.begin(), params.end(), bind1st(mem_fun(sFunc), aArr[i]));
    }
}

Outras dicas

Você quer algo assim ...

std::for_each(
  it->second.begin(),
  it->second.end(),
  std::bind1st(std::mem_fun(&A::operator()),x)
);

A expressão "bar.*Fn" não se avalia em ponteiro de função regular ou não membro. Portanto, você precisa chamar uma função de ligação (std :: tr1 :: bind ou boost :: bind) para obter essa função.

Não consegui fazer funcionar usando o formato atual, acho que não gosta do fato de que estou usando um ponteiro para uma função de membro da base e tentando chamar uma implementação de classes derivadas como essa.

Em vez disso, modifiquei o código para incluir funções virtuais puras na classe base que retornarão funções para cada classe derivada quando implementada. Não consigo pensar em mais nada que funcione. Mas compila como este.

Mas estou curioso para saber se alguém tiver uma solução para o problema original sem ter que usar os métodos virtuais "Criar functor" na classe base.

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