Temporäres Objekt vs push_back, pop_back - Was ist besser?



  • Folgendes gilt für beide Codeschnipsel:

    struct pod {
        // nicht sooo groß
    };
    //...
    std::vector <pod> vec;
    

    Die Frage ist: Lieber greedy hinzufügen, oder temporäres Objekt erstellen.
    (Oder doch eher ganz anders?)

    folgende Schnipsel stehen sich gegenüber:

    for (auto i = container.begin(); /* some loop stuff ;) */) {
        pod temp = getBlaBla(*i);
        if (temp.member == MEMBER_INVALID)
            throw("blubber");
        vec.push_back(temp);
    }
    
    for (auto i = container.begin(); /* some loop stuff ;) */) {
        vec.push_back(getBlaBla(*i));
        if(vec.rbegin()->member == MEMBER_INVALID)
            throw("blubber");
    }
    

    oder Scenario 2. Selbe Grundstruktur, nur keine Exception:

    for (auto i = container.begin(); /* some loop stuff ;) */) {
        pod temp = getBlaBla(*i);
        if (temp.member != MEMBER_INVALID)
            vec.push_back(temp);
    }
    
    for (auto i = container.begin(); /* some loop stuff ;) */) {
        vec.push_back(getBlaBla(*i));
        if(vec.rbegin()->member == MEMBER_INVALID)
            vec.pop_back();
    }
    


  • TempObject



  • Verwende das temporäre Objekt.
    Das Objekt einmal mehr zu kopieren ist weit empfehlenswerter, als es ungültig in den Vektor zu packen und dann mit dessen Iterator den Wert wieder rauszuholen.



  • Wieso überhaupt kopieren? Was ist getBlaBla?



  • Ich würde hier auch einfach

    pod const& temp = getBlaBla(*i);
    

    verwenden.
    (ob das unter C++11 allerdings noch eine Rolle spielt, weiß ich nicht 😉

    Gegen vector<T>.push_back() spricht auch, daß dann evtl. einmal Speicher neu reserviert werden würde (falls gerade size() >= capacity() wird).



  • Wenn getBlaBla(...) ein PR-Value ist, dann gibt es so ein "temporäres Objekt" so oder so. "temp object versus push_back/popback" wäre dann falsch.

    Vorschlag:

    #define FORWARD(x) std::forward<decltype(x)>(x)
    
    for (auto i = container.begin(); /* some loop stuff ;) */) {
        auto&& thing = getBlaBla(*i);
        if (thing.member != MEMBER_INVALID)
            vec.push_back(FORWARD(thing));
    }
    

    Das sollte etwas sinnvolles machen, unabhängig davon, ob getBlaBla eine Referenz zurück gibt oder nicht, und unabhängig davon, ob thing sich auf ein POD-Objekt bezieht oder nicht.

    Ob du da jetzt irgendwo eine Ausnahme werfen solltest, kann ich nicht beurteilen.


  • Mod


Log in to reply