Verschachtelte Templates [Erledigt]
-
Hallo,
ich würde gerne ein Template schreiben das eine generische Collection mit einem generischen Typ repräsentiert.
Mein Ansatz war folgender:template <typename Collection, typename Value> void ptree_to_collection(boost::property_tree::ptree& parent, Collection<Value> &col) { col.clear(); boost::property_tree::ptree p_child1; for (boost::property_tree::ptree::value_type &node : parent) { boost::property_tree::ptree child = node.second; Value value(child); col.emplace_back(std::move(value)); } }
Leider funktioniert das nicht und ich habe nur folgendes hinbekommen, aber dann muss man beim Funktionsaufruf immer explizit die Typen angeben:
template <typename Collection, typename Value> void ptree_to_collection(boost::property_tree::ptree& parent, Collection &col) { col.clear(); boost::property_tree::ptree p_child1; for (boost::property_tree::ptree::value_type &node : parent) { boost::property_tree::ptree child = node.second; Value value(child); col.emplace_back(std::move(value)); } }
Weiß vielleicht jemand weiter?
Danke im Voraus!
-
Was genau funktioniert denn nicht? Was ist die Fehlermeldung? Wie sieht dein Aufruf von ptree_to_collection aus? Und, bei Template Sachen und Typ Deduction, welcher Compiler in welcher Version (welcher C++ Standard ist implementiert)?
-
Probier das mal:
template <template <typename...> typename Collection, typename Value, typename... Tail> void ptree_to_collection(boost::property_tree::ptree& parent, Collection <Value, Tail...>& col);
Das erste nennt man template template parameter.
Und den Tail für alles was noch zum container gehört, was nicht der value_type ist (allocator, ..., je nachdem was man reingibt)
-
Nach das Template-Template-Problem geklärt ist ...
Die Funktion sieht aus, als möchte sie eigentlich ein Standardalgorithmus sein. Es gibt einige fragwürdige Sachen darin, z.B. warum derparent
als Nicht-const-Referenz übergeben wird, oder was der Sinn dieser Variablevalue
ist, oder wieso duemplace_back
stattpush_back
benutzt. Ich schätze, wenn man das alles aufräumt, bleibt am Ende entwederstd::transform(parent.begin(), parent.end(), std::back_inserter(col))
oder vielleicht auch dasselbe mitstd::move
übrig.Edit: Ah, das
.second
macht dem natürlich einen Strich durch die Rechnung.
-
@5cript
Danke, für deine Antwort. Mit dieser Komplexität habe ich ehrlich gesagt nicht gerechnet.
Ich denke, ich beschränke mich auf folgendes:template <typename Value> void ptree_to_collection(boost::property_tree::ptree& parent, std::vector<Value> &col) { col.clear(); boost::property_tree::ptree p_child1; for (boost::property_tree::ptree::value_type &node : parent) { boost::property_tree::ptree child = node.second; Value value(child); col.emplace_back(std::move(value)); } }
Denn letztendlich verwende ich std::vector.
Dennoch danke für deine Antwort!
-
@Bashar
Das ist ein wenig komplexer, da ich aus einem Typ einen komplett neuen Typ konstruiere:boost::property_tree::ptree child = node.second; Value value(child); col.emplace_back(std::move(value));
-
std::transform(parent.begin(), parent.end(), std::back_inserter(col), [](auto& node) { return Value{node.second}; });
-
@manni66 Ok, danke. Ich hatte damit rumgespielt und habe es nicht hinbekommen.