为什么vector :: push_back和emplace_back调用value_type :: constructor两次? [英] Why does vector::push_back and emplace_back call value_type::constructor twice?

查看:156
本文介绍了为什么vector :: push_back和emplace_back调用value_type :: constructor两次?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这个类:

class Foo {
public:
    Foo() {}
    Foo(const Foo&){cout << "constructed by lvalue reference." <<endl; }
    Foo(Foo&& ) {cout << "constructed by rvalue reference." << endl; }
};

然后插入一个向量:

Foo foo{};
vf.push_back(foo);

输出令人惊讶:

constructed by lvalue reference.
constructed by lvalue reference.

我假设它在传递参数时被复制,所以我试过:

I assume it got copied when passing parameters, so I tried:

vf.push_back(move(foo));

vf.push_back(forward<Foo>(foo));

由于移动语义但仍然调用构造函数两次,输出稍有不同:

The output are slightly different due to move semantics but still calling constructor twice:

constructed by rvalue reference.
constructed by lvalue reference.

为什么构造函数被调用了两次?它会影响多少性能?如何避免此问题?

Why the constructors got called twice? How much performance does it impact? How can I avoid this?

我使用 mingw-gcc-4.7.1 Windows Vista

I am using mingw-gcc-4.7.1 on Windows Vista

总示例:

#include <iostream>
#include <vector>

using namespace std;

class Foo {
public:
    Foo() {}
    Foo(const Foo&){cout << "constructed by lvalue reference." <<endl; }
    Foo(Foo&& ) {cout << "constructed by rvalue reference." << endl; }
};


int main(int argc, char **argv, char** envp)
{
    vector<Foo> vf;
    cout << "Insert a temporary." << endl;
    vf.emplace_back(Foo{});

    Foo foo{};
    cout << "Insert a variable." << endl;
    vf.emplace_back(foo);

    return 0;
}

精确输出:

Insert a temporary.
constructed by rvalue reference.
Insert a variable.
constructed by lvalue reference.
constructed by lvalue reference.


推荐答案

必须分配更多的内存来适应这些对象。当这种情况发生时,它需要将它的所有元素复制到新的内存位置。这将调用复制构造函数。所以当你插入你的元素,你将得到的构造函数的新元素和构造函数复制上一个元素。

When you insert new items in a vector the vector may have to allocate more memory to fit those objects. When that happens it needs to copy all it's elements to the new memory location. That will invoke the copy constructor. So when you insert your element you're getting the constructor for that new element and the constructor when copying the previous element.

这篇关于为什么vector :: push_back和emplace_back调用value_type :: constructor两次?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆