標準愚痴出力

個人的なIT作業ログです。もしかしたら一般的に参考になることが書いているかもしれません(弱気

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

よしよし