template <class T, class Allocator=std::allocator<T>> class vector { public: ... template <class... Args> void push_back(Args&&... args); };
このvariadicなpush_backはクラスTのコンストラクタの引数をとる
つまり、以下のように書ける
#include <vector> #include <string> using namespace std; struct person { int age; string name; person(int age, const string& name) : age(age), name(name) {} }; int main() { vector<person> v; v.push_back(23, "Akira"); v.push_back(38, "Johnny"); v.push_back(16, "Millia"); return 0; }
// before v.push_back(person(23, "Akira")); // after v.push_back(23, "Akira");
これができると何がうれしいかっていうと
shared_ptrをコンテナに入れるのがラクになることかな
vector<shared_ptr<person>> v; // before v.push_back(shared_ptr<person>(new person(23, "Akira"))); // after v.push_back(new person(22, "Akira"));
なお、std::vectorにはほかにもemplaceというメンバが追加される
template <class T, class Allocator=std::allocator<T>> class vector { public: ... template <class... Args> iterator emplace(const_iterator position, Args&&... args); };
これは上記のpush_backと同様に、クラスTのコンストラクタの引数をとる
push_backは最後尾に追加する要素のコンストラクトを行うが
emplaceは第1引数で指定された位置に追加する要素のコンストラクトを行う
(つまりはコンストラクタ引数をとるinsert)
正直、Variadic Templatesをコンストラクトに使うという発想はなかった・・・