右辺値参照~完全転送まで100%理解するぞ! part8 おまけ。
おまけ
可変引数テンプレートの Parameter Bagを展開しながら 全部出力する
#include<iostream> using namespace std; struct Concat{ template <class... T> void operator ()(T&&... t) { concat_(std::forward<T>(t)...); } private: void concat_() { } template <class Head, class... Tail> void concat_(Head&& head, Tail&&... tail) { cout << head; concat_(std::forward<Tail>(tail)...); } }; auto main() -> int { Concat con; con("test int:", 1 ); return 1; }
上記のように
template
今はcoutに出力しているが 当然 operator << を実装したくなる
#include<iostream> #include<sstream> using namespace std; struct Concat{ template <class... T> Concat& operator ()(T&&... t) { concat_(std::forward<T>(t)...); return *this; } friend ostream& operator << (ostream &os, Concat& obj); private: stringstream ss_; void concat_() { } template <class Head, class... Tail> void concat_(Head&& head, Tail&&... tail) { ss_ << head; concat_(std::forward<Tail>(tail)...); } }; inline ostream& operator << (ostream &os, Concat& obj){ os << obj.ss_.str(); obj.ss_.str(""); return os; } auto main() -> int { Concat con; cout << con("test int:", 1 ) << endl; return 1; }
operator() で thisを返し operator << にて streamへ。
最期に 再帰の部分をフリー関数へ(私の好み)
#include<iostream> #include<sstream> using namespace std; ostream& concat_( ostream &ss_) { return ss_; } template <class Head, class... Tail> ostream& concat_(ostream &ss_, Head&& head, Tail&&... tail) { ss_ << head; return concat_(ss_, std::forward<Tail>(tail)...); } struct Concat{ template <class... T> Concat& operator ()(T&&... t) { concat_(ss_, std::forward<T>(t)...); return *this; } friend ostream& operator << (ostream &os, Concat& obj); private: stringstream ss_; }; inline ostream& operator << (ostream &os, Concat& obj){ os << obj.ss_.str(); obj.ss_.str(""); return os; } auto main() -> int { Concat con; cout << con("test int:", 1 ) << endl; return 1; }