Domanda

Ho una classe che utilizza i funzioni come unità di lavoro. Accetta un riferimento a un functor nel suo metodo Run (). Per consentire a questa classe di operare su qualsiasi funzione, tutti questi funzioni devono derivare dalla mia classe funzione di base che assomiglia a questa:

class baseFunctor{

public:
    virtual void operator()()=0;
    virtual baseFunctor Clone()=0;
};

Funziona, tuttavia ovviamente limita questi agenti ad avere un metodo operatore che restituisce il vuoto e non accetta parametri. Devo essere in grado di accettare un funzione nella mia classe in grado di accettare qualsiasi tipo di parametro e restituire qualsiasi cosa. È apparentemente fattibile ma non riesco a trovare un modo per farlo. Ho preso in considerazione l'uso di modelli, ereditarietà multipla, ma continuo a essere vanificato dal fatto che la classe che deve eseguire questo funzione deve essere in grado di accettare qualsiasi tipo, quindi accetterà il tipo di classe di base e quindi non conoscerà il tipo effettivo del funzione.

Qualunque suggerimento su quale strada guardare sarebbe apprezzato.

È stato utile?

Soluzione

In che modo la classe che chiama il functor saprà quali parametri fornire e cosa fare con il valore restituito, se presente?

Altri suggerimenti

Quindi, se sto leggendo bene, hai un modello di " Visitor. " Potrebbe essere una buona cosa guardare in alto.

Qualcuno deve sapere che tipo è il funzione per dargli argomenti. Spesso con i funzione, gli argomenti vengono assegnati ai campi della classe derivata e l'operatore () opererà su quei campi. Cioè, il metodo stupido che chiama il functor e non ne sa nulla è dato dalla chiusura (metodo più argomenti tutti in una classe) da qualcuno più esperto.

Se vuoi funzioni generiche che accettano più argomenti nell'operatore (), il template ti porterà a metà strada lì, ma ne avrai bisogno per arity.

Sono d'accordo con Neil. La tua classe principale deve sapere quali parametri passare e quale valore di ritorno aspettarsi da questi funzioni. Puoi semplicemente digitare il cast del tuo " functor " a una classe appropriata che supporta la funzione con gli argomenti necessari e restituisce valore?

class baseFunctor
{
};

class functor1x2: public baseFunctor
{
public:
    virtual void* execute(void*, void*);

}

class MainClass
{
public:
   void Execute(baseFunctor* ipFunctor)
   {
      functor1x2* lpFunctor1x2 = dynamic_cast<functor1x2*>(ipFunctor);
      if(lpFunctor1x2)
      {
         lpFunctor1x2->execute(NULL, NULL);
      }
   }
}

Non sono sicuro di cosa si possa realizzare con questo approccio che non potrebbe essere più facilmente realizzato con il modello Visitatore, come ha osservato Drew.

Se sei aperto all'utilizzo della libreria Boost (www.boost.org), potresti trovare Boot.Bind e Boost.Function di particolare interesse. Li ho usati in passato per ottenere qualcosa di molto simile a quello di cui stai discutendo.

Se si utilizza Boost.Bind, è possibile eseguire il curry sui funzioni per tenere conto delle differenze tra il numero di argomenti previsti dal funzione e il numero di argomenti previsti dal metodo Run (ovvero, zero). Il codice che crea il functor dovrebbe associare qualsiasi argomento a valori specifici e quindi creare un functor a argomento zero che può essere passato a Run ().

MV

Perché vorresti restituire il functor? Stai memorizzando anche qualche stato? Qualche dettaglio in più sarà molto apprezzato dal momento che non è molto chiaro cosa esattamente si vuole fare.

Se si prevede di utilizzare l'ereditarietà, cercare i tipi di ritorno Covariant (e Idioma del costruttore virtuale ).

Ora, per la sostanza del problema: il problema non è in realtà con il passaggio in un funzione ma con l'applicazione di funzione. Potresti dare un'occhiata a boost :: lambda e boost :: parametro pure.

Penso che tu voglia un argomento con i puntini di sospensione, come varargs per C ++.

Forse la funzione std :: tr1 :: è interessante per te?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top