右辺値参照~完全転送まで100%理解するぞ! part7 可変引数テンプレート
前回の
template<class T> void hoge(T&& x){ std::forward<T>(x); }
universal referenceを使うことで、右辺値参照も左辺値参照もどちらも入ってくる
std::forwardを使うことで、右辺値参照の場合は ムーブコンストラクタ、左辺値参照の場合は コピーコンストラクタ が実行される
これでほぼ完ぺきだけど 完全転送と呼ぶには hoge(x,y,z...) と、可変引数に対応しなければいけません!
可変引数テンプレート
まずは可変引数テンプレートの説明
可変引数(printfのような va_list)のような書式で コンパイル時に展開される
#include<iostream> using namespace std; void bar( int i, string& s ){ cout << i << s << endl; }; template<class... T> void hoge(T... t){ bar(t...); } auto main() -> int { hoge(1, string(" test") ); // hoge(1); // hoge(int) は宣言されていないので エラー return 1; }
上記コードの template<class... T> で、0個以上の引数をもつものにヒットする bar(t...); で、tを展開したパラメーターを引数にもつ barを呼ぶ
barに必要なだけオーバーロードすればいい
あとはこれを universal reference と std::forwardを使い
#include<iostream> using namespace std; void bar( int i, string s ){ cout << i << s << endl; }; template<class... T> void hoge(T&&... t){ bar(std::forward<T>(t)...); } auto main() -> int { string s("s"); hoge(1, s ); hoge(1, " test" ); // hoge(1); // hoge(int) は宣言されていないので エラー return 1; }
これで、どんな引数でも完全転送が出来ました!
ま、ビットフィールド等 工夫しなければ完全転送できないパターンもあるようですが 一般的には これでOK