ADL und Rückgabewerte


  • Mod

    template <typename iter>
    typename std::remove_reference<decltype(*std::declval<iter>())>::type sum(iter begin_, iter end_)
    

    auto ist im Übrigen nicht nur Syntaxzucker. Wie wollt ihr sonst

    auto x = []{};
    

    schreiben?



  • Ok, wieder was gelernt 👍



  • Diese auto f() -> decltype() -Geschichte ist AFAIK auch nur Syntaxzucker (Vermeidung von Redundanz), berichtige mich bitte einer wenn ich falsch liege. Das Hauptargument dafür war ja dass man Bereichsauflösungen nicht mehr angeben muss und dass man sich auf die Argumente beziehen kann. Ersteres dürfte mit ausschreiben möglich sein (mir fällt im Moment kein Fall ein bei dem das nicht geht, habe aber irgendetwas mit verschachtelten Klassentemplates dazu im Hinterkopf) und letzteres mit std::declval (was natürlich auch in C++03 implementierbar ist).

    Arcoth schrieb:

    auto ist im Übrigen nicht nur Syntaxzucker. Wie wollt ihr sonst

    auto x = []{};
    

    schreiben?

    Hoppla, ja an Lambdas hab ich nicht gedacht, da hast du recht.

    An die TMP-Pros hier:
    Sind Variadic Templates Syntaxzucker wenn man von beliebig grossen Typlisten ausgeht?



  • asfdlol schrieb:

    An die TMP-Pros hier:
    Sind Variadic Templates Syntaxzucker wenn man von beliebig grossen Typlisten ausgeht?

    Jein.
    Wenn man so etwas wie Alexandrescus Typelist hat mit beliebiger Anzahl an Erstellungsmakros kann man afaik alle Algorithmen auf Listen von Typen und so Dinge wie Tuples implementieren.
    Was dann aber fehlt sind eine variable Anzahl an Parametern. Man muss dafür Tuple nehmen. Und auch Spezialisierungen für jede beliebige Funktion gehen dann nicht:

    template <typename R, typename ... Arg>
    struct foo<R(Arg...)> // wie ohne variadic templates?
    

    Man muss das dann wieder für jede Anzahl an Argumenten spezialisieren.
    Wenn man das aber außen vorlässt, dann ja, sind sie nur Syntaxzucker, allerdings einer von der Sorte, der sehr viel Redunanz spart.



  • Arcoth schrieb:

    auto ist im Übrigen nicht nur Syntaxzucker. Wie wollt ihr sonst

    auto x = []{};
    

    schreiben?

    Moment, also das hier geht auch ganz ohne auto :

    using lambda = void(*)();
    lambda x = []{};
    

    Also doch nur (sehr nützlicher) Syntax Sugar?



  • happystudent schrieb:

    Arcoth schrieb:

    auto ist im Übrigen nicht nur Syntaxzucker. Wie wollt ihr sonst

    auto x = []{};
    

    schreiben?

    Moment, also das hier geht auch ganz ohne auto :

    using lambda = void(*)();
    lambda x = []{};
    

    Also doch nur (sehr nützlicher) Syntax Sugar?

    Ja, aber sobald du etwas captures (?), gehts nicht mehr.



  • Nathan schrieb:

    Ja, aber sobald du etwas captures (?), gehts nicht mehr.

    Hm, wie wärs dann mit:

    std::function<void(void)> x = [=]{};
    

    ?

    Das geht bei mir auf jeden Fall...


  • Mod

    Ja, aber sobald du etwas captures (?), gehts nicht mehr.

    Stimmt schon, darauf wollte ich auch hinaus. Wenn du etwas capturest bekommt das closure-Objekt ja einen State.

    Ich meine mich zu erinnern dass camper erwähnt hat dass auto ursprünglich für Lambdas eingeführt wurde.

    Sind Variadic Templates Syntaxzucker wenn man von beliebig grossen Typlisten ausgeht?

    Wie willst du ein Lambda eine variable Anzahl von Argumenten nehmen lassen?

    [] (auto&&... a) {return f( std::forward<decltype(a)>(a)... );}
    

    Bei gewöhnlichen Funktionstemplates oder Klassentemplates kann man zwar für jede Länge explizit spezialisieren, ist aber auch verdammt hässlich.


  • Mod

    Hm, wie wärs dann mit:
    [..]

    Ist viel langsamer. Wenn du dann noch das Objekt an ein Funktionstemplate übergibst (wie std::copy_if o.ä.), wird es deutlich lahmer, weil ständig der Umweg über function gemacht wird.



  • Arcoth schrieb:

    Ist viel langsamer. Wenn du dann noch das Objekt an ein Funktionstemplate übergibst (wie std::copy_if o.ä.), wird es deutlich lahmer, weil ständig der Umweg über function gemacht wird.

    Hm, Ok.

    Aber eigentlich ist ein Lambda ja auch nur Syntax Sugar weil man sich ja genausogut (und trivial) immer einen Functor mit der selben Funktionalität bauen kann.

    Also braucht man auto eigentlich nur dann zwingend (= für nicht-Syntax Sugar) wenn man wiederum Syntax Sugar (nämlich ein Lambda) benutzen will. Somit wäre auto wiederum selbst nur Syntax Sugar.

    Oder?


  • Mod

    Ne, genauso trivial garantiert nicht. Lambdas sind einfach irre sexy.

    Boost.Lambda ist auch nett.

    Im Prinzip hast du aber recht.



  • Arcoth schrieb:

    Ne, genauso trivial garantiert nicht. Lambdas sind einfach irre sexy.

    Ja, das auf jeden Fall.

    Arcoth schrieb:

    Im Prinzip hast du aber recht.

    Die eigentliche Frage wäre halt, wo Syntax Sugar anfängt bzw. aufhört.

    Weil wenn man so argumentiert könnte man ja auch sagen dass templates auch nur Syntax Sugar sind und das ist dann glaube ich nicht mehr sinnvoll...



  • happystudent schrieb:

    Weil wenn man so argumentiert könnte man ja auch sagen dass templates auch nur Syntax Sugar sind und das ist dann glaube ich nicht mehr sinnvoll...

    Fast alle C++-Features sind Syntax Sugar. Bis auf RAII, SFINAE, constexpr und decltype kann man alles in C nachimplementieren.
    Und alles in C in Assembler. Und alles Assembler direkt als purer Machinencode.
    Aller Programmiersprachen sind Syntax Sugar, das ist der Sinn von ihnen!



  • Nathan schrieb:

    Fast alle C++-Features sind Syntax Sugar. Bis auf RAII, SFINAE, constexpr und decltype kann man alles in C nachimplementieren.
    Und alles in C in Assembler. Und alles Assembler direkt als purer Machinencode.
    Aller Programmiersprachen sind Syntax Sugar, das ist der Sinn von ihnen!

    Ja, schon 😃

    Aber dann ist der Begriff Syntax Sugar halt auch völlig sinnentleert und sagt letztendlich gar nichts aus.


  • Mod

    Die einzigen Möglichkeiten von einem Ausdruck* auf einen Typ zu kommen sind in C++03 folgende:

    • Der Ausdruck ist ein konstanter Ausdruck (Irgendein Zeiger, Integral oder Enumerator) und wird an ein Template als non-type-Argument übergeben.
    • Es wird sizeof auf den Ausdruck angewandt - und dann Schritt 1.

    Durch den zweiten Punkt wird BOOST_TYPEOF realisiert.

    Es ist also leider unmöglich so etwas einfach und portabel in C++03 umzusetzen.

    * Damit ist eine expression gemeint wie sie in der Standardgrammatik definiert ist.



  • Arcoth, was ist mit deinem Post über Karsten Ahnert geschehen? 😮



  • Forentroll schrieb:

    Arcoth, was ist mit deinem Post über Karsten Ahnert geschehen? 😮

    Spionagen werden vernichtet.



  • Der ist im anderen Thread.


Anmelden zum Antworten