Visual Studio 2010 では std::vector の emplace_back がバグっているという話なので、負荷の軽い方法を検討。
でも、検証プログラムのためにわざわざソリューション作るのもめんどいから、gcc で検証してみよう(おい
#include <cstdio> #include <string> #include <vector> class Foo { public: std::string value; Foo(const char *s); Foo(); ~Foo(); Foo(const Foo &); }; Foo::Foo(const char *s) : value(s) { puts("Foo:Foo(const char*)"); } Foo::Foo() { puts("Foo::Foo()"); } Foo::Foo(const Foo &other) : value(other.value) { puts("Foo::Foo(const Foo&)"); } Foo::~Foo() { puts("Foo::~Foo"); } int main() { std::vector<Foo> foos; foos.reserve(10); puts("**** push_back ****"); foos.push_back(Foo("ahaha")); puts("**** resize ****"); foos.resize( foos.size()+1 ); Foo &one=foos.back(); one.value = "ihihi"; puts("**** loop ****"); for(std::vector<Foo>::iterator p=foos.begin() ; p != foos.end() ; p++ ){ puts( p->value.c_str() ); } puts("**** end ****"); return 0; }
$ gcc -O2 foo.cpp -lstdc++ $ a **** push_back **** Foo:Foo(const char*) Foo::Foo(const Foo&) Foo::~Foo **** resize **** Foo::Foo() Foo::Foo(const Foo&) Foo::Foo(const Foo&) Foo::~Foo Foo::~Foo **** loop **** ahaha ihihi **** end **** Foo::~Foo Foo::~Foo
そんな馬鹿な!なぜ、resize してるだけなのに、そんなにコンストラクタが呼ばれるんだ!
だが、ここで auto &one=foos.back();
と書くと、one が整数型になってしまうことを思い出した。C++ の規格のバージョンが古いのかな?
ということで、C++11 を指定してみよう。
$ gcc -std=c++11 -O2 foo.cpp -lstdc++ <HAYAMA-PC:~/tmp> $ a **** push_back **** Foo:Foo(const char*) Foo::Foo(const Foo&) Foo::~Foo **** resize **** Foo::Foo() **** loop **** ahaha ihihi **** end **** Foo::~Foo Foo::~Foo
よしよし