Ich habe diesen Code:
#include <iostream>
using namespace std;
int print(int i)
{
cout << endl << i;
}
template<typename ...Args>
inline void pass(Args&&...args)
{
}
template<typename ...args>
inline void expand(args&&... a)
{
print(a) ...; //this doesn't expand
//pass( print(a)... ); this works
}
int main() {
expand(1,2,3,4);
return 0;
}
Es wirft einen Fehler:
In function 'void expand(args&& ...)':
error: expected ';' before '...' token
print(a) ...;
^
parameter packs not expanded with '...':
print(a) ...;
^
Warum ist die Verwendung der Funktion pass()
notwendig?
Das Erweitern eines Parameterpakets E...
erzeugt im Wesentlichen eine list E1, E2, [...], EN
, eine E
für jedes Element im Paket. Dieses syntaktische Konstrukt ist nur an Stellen gültig, an denen Listen grammatikalisch korrekt sind, z. B. in Funktionsaufrufen, Initialisierungslisten usw. Ein Ausdruck, der mehrere Kommaoperatoren enthält, zählt nicht.
Ich glaube, dass Sie mit fold-Ausdrücken ( N4295: Folding-Ausdrücke (Andrew Sutton, Richard Smith) ) einfach schreiben können:
(print(a), ...);
In diesem Ausdruck
print(a)
ist ein Ausdruck mit einem nicht erweiterten Parameterpaket.,
ist der Operator und ...
bezeichnet die Erweiterung der rechten Falte. Das Ergebnis des gesamten Ausdrucks ist, dass (print(a), ...)
in umgewandelt wird
print(a1) , (print(a2), (print(a3), print(a4))) // (assuming four elements).
Pack-Erweiterungen können nur in Pack-Erweiterungskontexten erfolgen. Dies sind im Wesentlichen:
Von diesen wäre die einfachere Verwendung in Ihrem Fall die letzte:
#include <iostream>
using namespace std;
int print(int i)
{
cout<<endl<<i;
return 0;
}
template<typename ...args>
inline void expand(args&&... a)
{
using expander = int[];
(void)expander{0, ((void)print(a), 0)...};
}
int main()
{
expand(1,2,3,4);
return 0;
}
Dieser funktioniert auch:
#include <iostream>
void print() {}
template<typename T, typename ... Types>
void print (T firstArg, Types ... args) {
std::cout << firstArg << "\n";
print(args...);
}
int main() {
print("Hello",1337,42.44,"World");
}