I dati sono memorizzati in una struttura ad albero C++ che ho letto da un file. L'albero è simile al seguente:Combinazione di modelli ed ereditarietà nella conversione dell'albero
class BaseNode {
std::vector<BaseNode*> children_;
...
};
class WhiteNode : public BaseNode { ... };
class BlackNode : public BaseNode { ... };
Dopo che l'albero è stato creato, vorrei convertirlo, ad es. a una stringa.
Al fine di mantenere il codice albero separato dal codice di conversione, vorrei utilizzare i modelli, vale a dire l'attuazione qualcosa di simile:
template <class T>
T WhiteNode::Convert() { ... };
Tuttavia, dal momento che i nodi della struttura vengono memorizzati come BaseNode*
, io don sapere come accedere a una funzione membro del modello. E poiché le funzioni dei membri del modello non possono essere ereditate, non penso che funzionerà.
sono venuto su con una soluzione di lavoro, però:
class BaseConversion {
public:
virtual ~BaseConversion() {}
virtual void * FromBlack() = 0;
virtual void * FromWhite() = 0;
};
template <class T>
class Conversion : public BaseConversion {
public:
void * FromBlack();
void * FromWhite();
};
class BaseNode {
std::vector<BaseNode*> children_;
virtual void * Convert(BaseConversion * conversion) = 0;
public:
virtual ~BaseNode() {}
template <class T>
T Convert() {
return *static_cast<T*>(Convert(new Conversion<T>));
}
};
class WhiteNode : public BaseNode {
void * Convert(BaseConversion * conversion) {
return conversion->FromWhite();
}
};
class BlackNode : public BaseNode {
void * Convert(BaseConversion * conversion) {
return conversion->FromBlack();
}
};
E la logica di trasformazione può essere completamente separati:
template <>
void * Conversion<std::string>::FromWhite() {
return new std::string("converting WHITE node to std::string ...");
}
template <>
void * Conversion<std::string>::FromBlack() {
return new std::string("converting BLACK node to std::string ...");
}
Testing il codice:
BaseNode * node = new BlackNode;
std::cout << node->Convert<std::string>() << std::endl;
node = new WhiteNode;
std::cout << node->Convert<std::string>() << std::endl;
rendimenti il risultato atteso:
converting BLACK node to std::string ...
converting WHITE node to std::string ...
Sebbene questa soluzione funzioni, sono sicuro che può essere eseguita molto più facilmente. Qualsiasi altra soluzione più semplice che ho trovato fallita, ad es. a causa della cancellazione del tipo.
Apprezzerei qualsiasi aiuto in merito. Grazie!
Grazie. Evitare il puntatore del vuoto potrebbe essere leggermente più elegante. Tuttavia, stavo cercando qualcosa di più compatto, forse senza conversioni o classi di visitatori. – DonDieselkopf
Questo non sarà completamente fattibile. Hai il supporto per C++ 11? –
Sì, sì. Se c'è una soluzione C++ 11, sarei curioso. In realtà mi aspettavo qualche soluzione simile a CRTP. Ma guardando la mia domanda, sono sempre più tentato di seguire il modello del visitatore. Tuttavia, qualsiasi altra opinione è molto gradita. – DonDieselkopf