Domanda

Ho una classe di template definita in questo modo:

template <class T>
class Command {
public:
    virtual T HandleSuccess(std::string response) = 0;
    virtual std::string FullCommand() const = 0;
    // ... other methods here ...
};

C ++ mi consentirà di creare una sottoclasse non modello di una classe modello? Quello che voglio dire è che posso fare una cosa del genere:

class NoopCommand : public Command<NoopResult> {
public:
    NoopResult HandleSuccess(std::string response);
    std::string FullCommand() const;
    // ... other methods here ...
};

Come non funziona per me perché dice che le seguenti funzioni virtuali non sono definite:

T admix::Command<T>::HandleSuccess(std::string) [with T = admix::NoopResult]
std::string admix::Command<T>::FullCommand() const [with T = admix::NoopResult]

Come posso definirli in modo specifico per la data T?

È stato utile?

Soluzione 5

litb ha trovato la soluzione su ## c ++ la scorsa notte.

Il problema era che stavo passando un NoopCommand a una funzione come questa:

void SendCommand(Command<T> command);

Quando avrei dovuto firmare questo:

void SendCommand(Command<T>& command);

Apportando tale modifica è possibile compilare tutto.

Altri suggerimenti

Come abbiamo capito in IRC, era perché hai

  1. Rendi le tue funzioni non pure
  2. Affettato la parte dell'oggetto derivato. Quindi le funzioni della classe base sono state chiamate perché l'oggetto non era più un oggetto derivato completo.

(Di seguito segue il mio sospetto su versioni precedenti della tua domanda - lo conservo per ulteriori considerazioni e per mantenere significativi i commenti)


Penso che il problema qui sia che il compilatore è libero di creare un'istanza di qualsiasi membro di funzione virtuale di un modello di classe anche se non viene utilizzato (ovvero non chiamato). Per creare un'istanza di una funzione è necessario fornire una definizione di funzione. Prova ad aggiungere questo nell'intestazione, dove il compilatore li troverà e creerà un'istanza di una definizione da:

template<typename T>
T Command<T>::HandleSuccess(std::string response) { /* put some default action ... */ }

template<typename T>
std::string Command<T>::FullCommand() const { /* put some default action ... */ }

C ++ Standard 14.7.1 / 9 :

  

Un'implementazione non deve istanziare implicitamente un modello di funzione, un modello di membro, un non virtuale   funzione membro, una classe membro o un membro di dati statici di un modello di classe che non richiede istanza. Non è specificato se un'implementazione istanzia implicitamente una funzione di membro virtuale di un modello di classe se la funzione di membro virtuale non sarebbe altrimenti istanziata.   

Le funzioni virtuali non sono definite in " significa che non hai definito i corpi funzione di NoopCommand :: HandleSuccess e NoopCommand :: FullCommand.

Quanto segue dovrebbe risolvere il tuo problema.

class NoopCommand : public Command<NoopResult> {
public:
    NoopResult HandleSuccess(std::string response) {}
    std::string FullCommand() const {}
    // ... other methods here ...
};

Oppure hai un NoopCommand.cpp, assicurati che sia incluso nel tuo processo di compilazione.

Il modello che utilizzi è ampiamente noto come " Modello di modello curiosamente ricorrente " . quindi sì, puoi farlo.
Non riesco a pensare a un motivo per cui non viene compilato.

Il codice che hai fornito viene compilato per me, senza errori (dopo aver aggiunto un struct NoopResult {}; ). Forse c'è un problema nel codice che hai lasciato fuori?

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