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?
-
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. aufiterator_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...
-
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
-
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 }
-
@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.
-
-
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 neueusing
-Syntax nicht gehen muss.
Das ursprüngliche Problem ist damit gelöst.
-
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).