私はこのコードを持っています:
_#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;
}
_
エラーをスローします:
_ In function 'void expand(args&& ...)':
error: expected ';' before '...' token
print(a) ...;
^
parameter packs not expanded with '...':
print(a) ...;
^
_
pass()
関数の使用が必要なのはなぜですか?
基本的に、パラメータパック_E...
_を展開すると、list_E1, E2, [...], EN
_が生成され、1つのE
がパック。この構文構成は、リストが文法的に正しい場所(関数呼び出し、初期化リストなど)でのみ有効です。複数のコンマ演算子を含む式はカウントされません。
折りたたみ式 ( N4295:折りたたみ式(アンドリューサットン、リチャードスミス) )を使用すると、次のように簡単に記述できると思います。
_(print(a), ...);
_
この表現では、
print(a)
は、展開されていないパラメーターパックを含む式です。,
_は演算子であり、...
_は、右折りたたみ展開を指定します。式全体の結果は、_(print(a), ...)
_が次のように変換されることです。
_print(a1) , (print(a2), (print(a3), print(a4))) // (assuming four elements).
_
パック展開は、パック展開コンテキストでのみ発生します。これらは基本的に次のとおりです。
これらのうち、あなたのケースで使いやすいのが最後です:
#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;
}
これも機能します:
#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");
}