std::vector の emplace_back が使えない状況で、軽い push を検討する

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

よしよし