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 der parent als Nicht-const-Referenz übergeben wird, oder was der Sinn dieser Variable value ist, oder wieso du emplace_back statt push_back benutzt. Ich schätze, wenn man das alles aufräumt, bleibt am Ende entweder std::transform(parent.begin(), parent.end(), std::back_inserter(col)) oder vielleicht auch dasselbe mit std::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));
    


  • @Steffo

    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. 😅


Anmelden zum Antworten