for Schleife vs std::for_each + lambda


  • Mod

    Sone schrieb:

    sone__mess schrieb:

    2. WTF:
    begin() wird nicht geadlt.

    Ja, dafür muss was her was §6.5.4/1 entspricht.

    Eine kleine Hilfsfunktion?



  • knivil schrieb:

    D.h. Iteratoren sind in idiomatischem C++ vorzuziehen, also auch vor for(auto e: cont) { ... } . Deswegen ist for_each nur konsequent.

    Ne, du musst von deinem funktionalen Denken wegkommen. std::for_each() über einen ganzen Container mit Lambdas aufrufen bringt meist nichts, weil man das Gleiche einfacher über Range-Based For erreichen kann.

    knivil schrieb:

    Nun, mitlerweile hat man gemerkt, dass man sowieso meist mit ganzen Containern arbeitet, zumal sich Iteratoren nur schlecht kombinieren lassen.

    Was meinst du damit?



  • Sone schrieb:

    Nexus schrieb:

    Warum decltype(determine_type(range)) und nicht auto&& ?

    Hab ich gar nicht gesehen. Ich habe den Trick schon im Standard gefunden, dann aber wieder vergessen. 🙂
    Das [[noreturn]] war jetzt analog zu declval, nur so als Hinweis dass diese Funktion niemals aufgerufen werden soll und keiner nach einer Definition suchen soll. (Hätte zwar auch ein Kommentar getan, aber tja).

    Wie wär's in dem Fall mit = delete; ? 😉

    [[noreturn]] würde mir immer noch erlauben, die Funktion zu definieren und aufzurufen, was wann zu UB führt...



  • camper schrieb:

    Sone schrieb:

    sone__mess schrieb:

    2. WTF:
    begin() wird nicht geadlt.

    Ja, dafür muss was her was §6.5.4/1 entspricht.

    Eine kleine Hilfsfunktion?

    namespace RangeAccess
    {
    	using std::begin;
    
    	template<typename C>
        inline auto adlbegin( C&& c ) -> decltype( begin(std::forward<C>(c)) )
        { return begin(std::forward<C>(c)); }
    
    	using std::end;
    
    	template<typename C>
        inline auto adlend( C&& c ) -> decltype( end(std::forward<C>(c)) )
        { return end(std::forward<C>(c)); }
    }
    

    ? Oder muss für const und non- const lvalue-Referenzen definiert werden?



  • Range-based loops laufen doch auch über Iteratoren, sind also genauso konsequent.

    Mir ging es um das Sprachmittel, nicht darum, das dahinter auch nur Iteratoren benutzt werden. Weil dann muss diese Kette konsequent bis Asm fortgefuehrt werden.

    Die Syntax ist zwar eine andere, aber insgesamt sind sie doch deutlich einfacher zu lesen, vor allem wenn man auch noch auto als Typ verwendet.

    Ja stimme ich zu, habe ich erwaehnt.



  • Nexus schrieb:

    knivil schrieb:

    D.h. Iteratoren sind in idiomatischem C++ vorzuziehen, also auch vor for(auto e: cont) { ... } . Deswegen ist for_each nur konsequent.

    Ne, du musst von deinem funktionalen Denken wegkommen. std::for_each() über einen ganzen Container mit Lambdas aufrufen bringt meist nichts, weil man das Gleiche einfacher über Range-Based For erreichen kann.

    knivil schrieb:

    Nun, mitlerweile hat man gemerkt, dass man sowieso meist mit ganzen Containern arbeitet, zumal sich Iteratoren nur schlecht kombinieren lassen.

    Was meinst du damit?

    1.) Nun, ich habe aus einer bestimmten Sicht argumentiert. Hier war es die ideomatische Sichtweise von pre-C++11 mit Iteratoren als Containerabstraktion fuer Algorithmen. Ich persoenlich nehme ganz klar for(auto e: cont) { ... } .
    2.) Es ist in C++ schwierig, wie in funktionalen Sprachen, sort, accumulate, reduce etc. einfach zu kombinieren. Ein Grund dafuer ist, Iteratoren als Abstraktion zu verwenden. Wie implementiere ich beispielsweise zip und wende dann ein accumulate darauf an? Macht man einfach nicht, weils sehr umstaendlich ist, das kanonisch ueber Iteratoren als Abstraktion zu realisieren. Ranges loesen das Problem nicht.


Anmelden zum Antworten