Das Beispiel im Beitrag lässt sich gut kompilieren, aber ich habe es nicht geschafft, es mit Funktionsvorlagen zum Laufen zu bringen.
Kann jemand helfen, die korrekte Syntax herauszufinden (falls vorhanden)?
int max(int n) { return n; } // end condition
template <int... N> // replacing int... with typename... works
int max(int n, N... rest) // !! error: unknown type name 'N'
{
int tmp = max(rest...);
return n < tmp? tmp : n;
}
#include <iostream>
int main()
{
std::cout << max(3, 1, 4, 2, 5, 0) << std::endl;
}
Ich dachte ein Variadic max existiert bereits in der Standardbibliothek… aber ich bin mir nicht ganz sicher.
– Kerrek SB
24. Okt ’11 um 15:03
@Kerrek max ist nicht der Punkt, es ist nur ein Beispiel.
– Motti
24. Okt. ’11 um 15:20
Möchtest du ein Nicht-Kompilierungszeit Funktion (dh max(3,1,4,foo(),5,bar()) im Gegensatz zu max<3,1,4,2,5,6>()), die eine beliebige Anzahl von Parametern benötigt, alle vom gleichen Typ? Und was bringt das Maximum?
– Aaron McDaid
1. Februar ’12 um 1:35
@AaronMcDaid, ja, ich habe nach einer Funktion ohne Kompilierzeit gesucht. Dank der Erklärungen von Konrad & Luc habe ich seitdem die Fehler meines Weges gesehen.
– Motti
1. Februar ’12 um 7:13
Warten Sie, warum sagen Sie, dass gcc dies nicht unterstützt? Kompiliert gut mit 4.9
– RamblingMad
10. Juli ’15 um 22:54
Konrad Rudolph
Sie verwechseln einfach Typnamen und Nichttypnamen. Was Sie wollen, funktioniert einfach nicht.
Sie kann Verwenden Sie wahrscheinlich variadische Nicht-Typ-Vorlagen in Funktionen, aber nicht als (Nicht-Vorlagen-)Argumente:
template <int N, int... Rest>
int max()
{
int tmp = max<Rest...>();
return N < tmp ? tmp : N;
}
… obwohl ich das nicht getestet habe und mir nicht sicher bin wie Dies sollte funktionieren, da Sie als Basisfall eine Teilspezialisierung benötigen. Sie könnten dies lösen, indem Sie an eine teilweise spezialisierte Struktur senden:
template <int N, int... Rest>
struct max_t {
static int const value = max_t<Rest...>::value > N ? max_t<Rest...>::value : N;
};
template <int N>
struct max_t<N> {
static int const value = N;
};
template <int... NS>
int max()
{
return max_t<NS...>::value;
}
Das wird funktionieren.
Ich suche keine Kompilierzeitfunktion. Durch die Nutzung typename... N wir erhalten das gleiche Verhalten, da die Parameter schließlich gezwungen werden zu int (der erste Parameter für jede Überladung von max ist int) aber es ist (IMO) etwas weniger elegant, das möchte ich konkretisieren diese Funktion nimmt eine beliebige Anzahl eines bestimmten Typs an. Eins könnten benutzen initializer_list aber dann müsste die Anrufseite geschweifte Klammern verwenden.
– Motti
24. Okt. 11 um 15:29 Uhr
@Motti Wie mein erster Absatz sagt, funktioniert das, was Sie wollen, einfach nicht.
– Konrad Rudolph
24. Okt. 11. um 16:36 Uhr
@Motti template<int I> void foo(I i); wäre unsinnig. Sie müssen das verstehen, bevor Sie variadisch werden.
– Luc Danton
24. Okt. ’11 um 16:44 Uhr
@Motti: Wenn Sie nicht nach einer Kompilierzeitfunktion suchen, suchen Sie auch nicht nach Vorlagenparametern, die nicht vom Typ sind. Nicht-Typ-Vorlagenparameter müssen konstante Ausdrücke zur Kompilierzeit sein.
– Ben Voigt
24. Okt. 11 um 16:56 Uhr
@LucDanton Wenn Sie es so ausdrücken, ist es offensichtlich, dass variadische Vorlagen meine Intuition durcheinanderbringen. Anscheinend grok ich sie noch nicht.
– Motti
24. Okt. 11 um 18:36 Uhr
parker0203
Dadurch werden alle Elemente ausgedruckt, get max könnte ähnlich implementiert werden
template <int N>
void foo(){
cout << N << endl;
}
template <int N, int M, int ... Rest>
void foo(){
cout << N << endl;
foo<M, Rest...>();
}
int main(){
foo<1, 5, 7>();
return 0;
}
Ich mag die Art und Weise, wie Sie die Mehrdeutigkeit vermeiden.
– Bausatz Fisto
25. Juli ’13 um 16:03
@parker0203 Warum benötigt die primäre Vorlage drei Vorlagenargumente? ich dachte template <int N, int ... Rest>foo(){ foo<Rest...>(); } würde genügen.
– Olumid
29. November ’16 um 13:12
Es reicht nicht, deshalb sind die M, N, Rest… alle notwendig, MSVC 2017 spuckt Fehler aus, wenn sie mit foo<1,2>() aufgerufen werden; error C2668: ‘foo’: Mehrdeutiger Aufruf einer überladenen Funktion könnte ‘void foo<2,>(void)’ oder ‘void foo<2>(void)’ sein.
– zhaorufei
8. September ’21 um 9:25
Hier sind zwei Möglichkeiten, eine variadische Funktionsvorlage zu definieren, die nur akzeptiert int Parameter. Der erste erzeugt bei der Instanziierung einen harten Fehler, der zweite verwendet SFINAE:
Wie Sie sehen, werden hier keine typfremden Vorlagenparameter verwendet.
sehr interessante Verwendung von Vorlagen. kann auch wenige Anwendungen haben. 🙂
– KaffeeEntwickler
28. Juni ’13 um 1:23
Gute Idee, aber das funktioniert in keiner GCC-Version. > Fehler: mit 2 Vorlagenparametern neu deklariert > > Hinweis: vorherige Deklaration ‘template struct and_’ used 1 . godbolt.org/g/cQDSA0
– Benutzer877329
29. Dezember ’16 um 14:11
Richard Smith
Die Lösung von Luc Danton verhält sich nicht korrekt mit Parametern, die nicht vom Typ sind int, kann aber implizit in an . umgewandelt werden int. Hier ist eine, die tut:
template<typename T, typename U> struct first_type { typedef T type; };
template<typename T> int max_checked(T n) { return n; }
template<typename T1, typename T2, typename ...Ts>
int max_checked(T1 n1, T2 n2, Ts ...ns)
{
int maxRest = max_checked(n2, ns...);
return n1 > maxRest ? n1 : maxRest;
}
template<typename ...T> auto max(T &&...t) ->
decltype(max_checked<typename first_type<int, T>::type...>(t...))
{
return max_checked<typename first_type<int, T>::type...>(t...);
}
struct S { operator int() { return 3; } };
int v = max(1, 2.0, S()); // v = 3.
Hier, max leitet alle Argumente unverändert an . weiter max_checked, das die gleiche Anzahl von Argumenten vom Typ . akzeptiert int (bereitgestellt durch Durchführen einer Pack-Erweiterung auf dem first_type Schablone). Der decltype(...) Rückgabetyp wird verwendet, um SFINAE anzuwenden, wenn ein Argument nicht konvertiert werden kann in int.
So erreichen Sie variadische Argumente in Ihrem max Beispiel so, dass es eine beliebige Anzahl von arithmetischen Argumenten annehmen kann:
Dies ist gut, da es jeden numerischen Typ annehmen kann und die maximale Zahl nach ihrem ursprünglichen Typ zurückgibt, anstatt nur int, auch.
Wenn ich das laufe, ist die Art von res ist double nicht long. Wie auch immer, ich habe versucht, Nicht-Typ-Vorlagenparameter zu verstehen. Ihre Lösung ist zwar cool, aber nicht das, wonach ich gesucht habe. Danke trotzdem. ideone.com/gUnoLp
– Motti
12. Juli ’15 um 10:36
Wenn ich das laufe, ist die Art von res ist double nicht long. Wie auch immer, ich habe versucht, Nicht-Typ-Vorlagenparameter zu verstehen. Ihre Lösung ist zwar cool, aber nicht das, wonach ich gesucht habe. Danke trotzdem. ideone.com/gUnoLp
– Motti
12. Juli ’15 um 10:36
.
2150300cookie-checktypunabhängige variadische Funktionsvorlagen in C++11yes
Ich dachte ein Variadic
max
existiert bereits in der Standardbibliothek… aber ich bin mir nicht ganz sicher.– Kerrek SB
24. Okt ’11 um 15:03
@Kerrek
max
ist nicht der Punkt, es ist nur ein Beispiel.– Motti
24. Okt. ’11 um 15:20
Möchtest du ein Nicht-Kompilierungszeit Funktion (dh
max(3,1,4,foo(),5,bar())
im Gegensatz zumax<3,1,4,2,5,6>()
), die eine beliebige Anzahl von Parametern benötigt, alle vom gleichen Typ? Und was bringt das Maximum?– Aaron McDaid
1. Februar ’12 um 1:35
@AaronMcDaid, ja, ich habe nach einer Funktion ohne Kompilierzeit gesucht. Dank der Erklärungen von Konrad & Luc habe ich seitdem die Fehler meines Weges gesehen.
– Motti
1. Februar ’12 um 7:13
Warten Sie, warum sagen Sie, dass gcc dies nicht unterstützt? Kompiliert gut mit 4.9
– RamblingMad
10. Juli ’15 um 22:54