using zwischen template und Signatur?



  • Hallo,

    ich fände es sehr praktisch wenn man using (bzw typdef) zwischen der template Liste und der Signatur einer Funktion erstellen könnte. Also etwa so:

    template <typename Iterator>
    using T = decltype(*Iterator()) // Ist nur für die folgende Funktion gültig
    T calculate_something(Iterator start, Iterator end, T start_value)
    {
        // Mach irgendwas
    }
    

    Jedesmal decltype (am schlimmsten noch mit std::remove_reference) zu verwenden bläht finde ich die Funktionssignatur extrem auf und macht diese sehr unübersichtlich.

    Wie fändet ihr das? Ist so ein Feature eventuell geplant, oder wird für absehbarer Zukunft in solchen Fällen nichts anderes bleiben als ewig lange Funktionssignaturen zu schreiben?


  • Mod

    template <typename Iterator,
              typename T = decltype(*std::declval<Iterator>())>
    T calculate_something(Iterator start, Iterator end, T start_value)
    {
        // Mach irgendwas
    }
    

    ?
    Übrigens würde ich in dem Fall evt. auf iterator_traits<>::value_type zurückgreifen.



  • Arcoth schrieb:

    template <typename Iterator,
              typename T = decltype(*std::declval<Iterator>())>
    T calculate_something(Iterator start, Iterator end, T start_value)
    {
        // Mach irgendwas
    }
    

    Ja das geht schon, aber damit "verunreinige" ich ja dann meine template-Argument Liste (heißt das so?) mit Sachen die da eigentlich nicht reingehören. Also angenommen T muss sowieso der Werte-Typ des Iterators sein, dann macht es ja keinen Sinn das vom User konfigurierbar zu lassen...


  • Mod

    Dann schreib' doch eine auxiliare Funktion.

    namespace detail {
      template <typename Iterator,
                typename T = decltype(*std::declval<Iterator>())>
      T calculate_something(Iterator start, Iterator end, T start_value)
      {
          // Mach irgendwas
      }
    }
    template <typename... Args>
    auto calculate_something(Args&&... args)
      -> decltype(detail::calculate_something(std::forward<Args>(args)...))
    {return       detail::calculate_something(std::forward<Args>(args)...);}
    

    Mit impliziten Template-Parametern könnte man deine Idee im Übrigen direkt umsetzen. Hoffentlich kommen die rein!



  • Arcoth schrieb:

    Dann schreib' doch eine auxiliare Funktion.

    namespace detail {
      template <typename Iterator,
                typename T = decltype(*std::declval<Iterator>())>
      T calculate_something(Iterator start, Iterator end, T start_value)
      {
          // Mach irgendwas
      }
    }
    template <typename... Args>
    auto calculate_something(Args&&... args)
      -> decltype(detail::calculate_something(std::forward<Args>(args)...))
    {return       detail::calculate_something(std::forward<Args>(args)...);}
    

    Hm, das find ich jetzt ehrlich gesagt noch schlimmer 😃
    Weil jetzt hab ich ja gar keine Info mehr was (bzw. wie viele) Argumente calculate_something entgegen nimmt und welche Vorraussetzungen die erfüllen müssen.

    Nach außen hin sieht das dann aus als könte ich beliebige Argumente in die Funktion reinjagen (was ja nicht der Fall ist) und der Rückgabewert erschließt sich auch nicht ohne in die detail Implementierung zu gucken...

    Arcoth schrieb:

    Mit impliziten Template-Parametern könnte man deine Idee im Übrigen direkt umsetzen. Hoffentlich kommen die rein!

    Ok, das klingt ja schonmal gut, muss ich gleich mal googlen 🙂


  • Mod

    happystudent schrieb:

    Ok, das klingt ja schonmal gut, muss ich gleich mal googlen 🙂

    Entschuldige, Ich vergaß zu erwähnen dass diese noch gar nicht standardisiert und noch weniger implementiert sind. Sie sind für C++1Z geplant.
    (Das "Hoffentlich kommen die rein" bezog sich auf's Reinkommen in den Standard)

    Nach außen hin sieht das dann aus als könte ich beliebige Argumente in die Funktion reinjagen (was ja nicht der Fall ist) und der Rückgabewert erschließt sich auch nicht ohne in die detail Implementierung zu gucken...

    Es gibt für dein Problem eben AFAICS keine sonderlich elegante Lösung. 😃



  • template <typename Iterator>
    auto calculate_something(Iterator start, Iterator end, decltype(*Iterator()) start_value) -> decltype(start_value)
    {
        // Mach irgendwas
    }
    

  • Mod

    @TyRoXx: Erster April war gestern.



  • Arcoth schrieb:

    Entschuldige, Ich vergaß zu erwähnen dass diese noch gar nicht standardisiert und noch weniger implementiert sind. Sie sind für C++1Z geplant.
    (Das "Hoffentlich kommen die rein" bezog sich auf's Reinkommen in den Standard)

    Ach so, Ok... Dann hoffe ich das einfach auch mal 😃

    Arcoth schrieb:

    Es gibt für dein Problem eben AFAICS keine sonderlich elegante Lösung. 😃

    Schade, aber ich habs schon befürchtet.



  • Arcoth schrieb:

    @TyRoXx: Erster April war gestern.

    Danke für die Erinnerung.


  • Mod

    TyRoXx schrieb:

    Arcoth schrieb:

    @TyRoXx: Erster April war gestern.

    Danke für die Erinnerung.

    Dachtest du etwa dass dem TE nicht bewusst war dass Funktionsparametertypen auch decltype-specifier sein dürfen?



  • Arcoth schrieb:

    Dachtest du etwa dass dem TE nicht bewusst war dass Funktionsparametertypen auch decltype-specifier sein dürfen?

    Darum geht es gar nicht. Meine Lösung verwendet den Parametertyp als Rückgabetyp wieder, sodass man den Umweg über typename oder eine neue using -Syntax nicht gehen muss.
    Das ursprüngliche Problem ist damit gelöst.


  • Mod

    TyRoXx schrieb:

    Meine Lösung verwendet den Parametertyp als Rückgabetyp wieder

    Ahh, ich verstehe. Ich hatte die Frage gar nicht vollständig gelesen (Effizienz und so) und nahm an dass es um ein kosmetisches Problem ging, nicht um DRY. 💡



  • Wieso dann nicht gleich -> auto schreiben?

    Nene, ich denke dem happystudent ging es schon (zumindest auch) um Kosmetik.
    Und es gibt ja auch Fälle wo es nicht bloss um nen einzelnen Parameter geht, und der Ausdruck für den Typ wirklich ordentlich lange wird.



  • Ja, also es ging mir schon (auch) um "Kosmetik" wenn man so will 😃

    Mich nervt halt bei solchen template-Monstern vor allem die Parameterliste die man vom Intellisense angezeigt bekommt - da kann man oft gar nichts mehr erkennen weil alles voll von typename/decltype/declval/enable_if Gerümpel ist... (die Deklaration an sich ja auch, was die Lesbarkeit halt einfach erschwert).


Log in to reply