Suppongo di ricevere due argomenti per un modello, T1 e T2. Se so T1 è di per sé una classe su modelli (ad esempio, un contenitore), e T2 posso essere qualsiasi cosa, è possibile per me per determinare il tipo di modello base per il T1 e ricostruirlo usando T2 come argomento?È possibile districare un modello dai suoi argomenti in C++?
Ad esempio, se ricevo std::vector<int>
e std::string
, vorrei creare automaticamente std::vector<std::string>
. Tuttavia, se mi fosse data std::set<bool>
e double
, produrrebbe std::set<double>
.
Dopo aver esaminato type_traits, blog pertinenti, e altre domande qui, non vedo un approccio generale per risolvere questo problema. L'unico modo che posso attualmente vedere per eseguire questa attività è creare adattatori di template per ogni tipo che può essere passato come T1.
Per esempio, se ho avuto:
template<typename T_inner, typename T_new>
std::list<T_new> AdaptTemplate(std::list<T_inner>, T_new);
template<typename T_inner, typename T_new>
std::set<T_new> AdaptTemplate(std::set<T_inner>, T_new);
template<typename T_inner, typename T_new>
std::vector<T_new> AdaptTemplate(std::vector<T_inner>, T_new);
dovrei essere in grado di utilizzare decltype e si basano su l'overloading degli operatori per risolvere il mio problema. Qualcosa sulla falsariga di:
template <typename T1, typename T2>
void MyTemplatedFunction() {
using my_type = decltype(AdaptTemplate(T1(),T2()));
}
Mi manca qualcosa? C'è un approccio migliore?
Perché voglio fare questo?
Sto costruendo una libreria C++ in cui voglio semplificare ciò che gli utenti devono fare per creare modelli modulari. Ad esempio, se un utente desidera creare una simulazione basata su agenti, potrebbe configurare un modello Mondo con un tipo di organismo, un gestore della popolazione, un gestore dell'ambiente e un gestore sistematico.
Ognuno dei manager hanno bisogno anche di conoscere il tipo organismo, in modo da una dichiarazione potrebbe essere simile:
World< NeuralNetworkAgent, EAPop<NeuralNetworkAgent>,
MazeEnvironment<NeuralNetworkAgent>,
LineageTracker<NeuralNetworkAgent> > world;
Preferirei mille volte gli utenti non devono ripetere NeuralNetworkAgent
ogni volta. Se io sono in grado di cambiare gli argomenti di template, quindi gli argomenti di default possono essere utilizzate e quanto sopra possono essere semplificate a:
World< NeuralNetworkAgent, EAPop<>, MazeEnvironment<>, LineageTracker<> > world;
Inoltre è più facile convertire da un tipo ad un altro mondo, senza preoccuparsi di errori di tipo.
Naturalmente, non posso che fare con la maggior parte degli errori usando static_assert e trattare solo con le dichiarazioni più lunghi, ma mi piacerebbe sapere se la soluzione migliore è possibile.
Tutte e tre le risposte che ho ricevuto erano eccellenti. Quello di @Barry è il più completo e quello di T.C. risolve il mio problema di fondo al meglio, ma penso che la risposta di Sam Varshavchik (che ho accettato) sia la più elegante per risolvere la domanda come ho chiesto. Grazie mille a tutti! –
Dato che questo post è un duplicato, penso che quello indicato da @Ben Voight sia molto simile, ma in particolare è focalizzato sull'STL. Se tutti i modelli in questione provengono dalla stessa libreria, ci sono sicuramente trucchi extra che potrebbero essere possibili. Detto questo, l'altra domanda ha anche alcune risposte interessanti e utili. Detto questo, trovo le risposte qui fornite più mirate a questa domanda e più immediatamente utili. –
Sebbene l'altra domanda sia meno ampia, le risposte coprono completamente il tuo caso. Ecco perché la mia bandiera risulta in un banner che dice "La tua domanda ha già una risposta qui". –