読者です 読者をやめる 読者になる 読者になる

C++0x コンストラクタの引数をとる push_back

C++

C++0xのstd::vectorは以下のようになっている

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をコンストラクトに使うという発想はなかった・・・