Pregunta

Tengo una clase abstracta funtor que sobrecarga del operador () y derivados objetos que implementan.

Tengo una función (parte de otra clase) que trata de tomar una serie de estas clases functor y trata de pasar un puntero a una función miembro de la for_each algoritmo de STD (), aquí es una visión general de lo que soy haciendo:

EDIT:. He vuelto a limpiar y poner el viejo pequeño ejemplo para mayor claridad

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
}

He intentado varias formas y no puedo encontrar la manera de conseguir que funcione, necesito utilizar el tipo abstracto que pude tener diferentes tipos derivados, pero todos ellos tendrán que implementar el mismo operador () (PARAM x) función.

Sólo necesito la función for_each () para ser capaz de llamar a la operadora función miembro () (parámetro x). Tengo una función diferente donde tiene implementaciones concretas y simplemente pasa una instancia de aquellos y funciona. Estoy intentando conseguir un efecto similar aquí, pero sin el conocimiento de lo que las clases concretas que me dan.

¿Qué estoy haciendo mal?

¿Fue útil?

Solución

Si entiendo lo que quiere hacer, hay un buen número de errores en el fragmento de código:

  • sizeof aArr está mal, que necesita para aprobar el tamaño de forma explícita (observado por ChrisW)
  • Falta de especificador virtual en la declaración original de operator()()
  • No sabe dónde termina el bucle for ya que no hay coincidencia } (sospecho que no debería estar allí en absoluto)

Aquí hay un código que bucle a través de una matriz de A (o A derivado) objetos y llamará operator() en cada uno, pasando a través de un argumento pasado-en que el parámetro param:

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

es necesario mem_fun() para convertir un puntero de función miembro de 1-parámetro a un objeto de función 2-parámetro; bind2nd() produce entonces de que un objeto de función 1-parámetro que fija el argumento suministrado a function() como el segundo argumento. (for_each() requiere un puntero de función 1-parámetro u objeto de función.)

EDIT: Basado en de Alex Tingle respuesta , yo inferir que es posible que haya querido function() hacer muchas cosas en un solo objeto A derivados. En ese caso, usted querrá 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]));
    }
}

Otros consejos

¿Quieres algo como esto ...

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

La expresión "bar. * Fn" no se evalúa como regular o no miembro, puntero de función. Así que hay que llamar a una función de unión (ya sea std :: TR1 :: bind o boost :: bind) para obtener una función de este tipo.

No pude conseguir que funcione con el formato actual, creo que no le gusta el hecho de que estoy usando un puntero a una función miembro de base y tratando de llamar a una implementación de las clases derivadas de esa manera.

En lugar de eso modificó el código para incluir funciones virtuales puras en la clase base que devolverá funtores para cada clase derivada cuando se implementa. No puedo pensar en otra cosa que trabajar. Pero compila como este.

pero tengo curiosidad si alguien tiene una solución al problema original sin tener que utilizar métodos virtuales puros "crear" funtor en la clase base.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top