📜  C++ STL向量中的push_back()vs emplace_back()(1)

📅  最后修改于: 2023-12-03 15:13:57.137000             🧑  作者: Mango

C++ STL向量中的push_back() vs emplace_back()

在C++ STL中,vector是一个非常有用的容器,它可以存储同种类型的元素并提供许多有用的函数来操作这些元素。其中最常用的两个函数是push_back()和emplace_back(),这两个函数都是向向量的末尾插入一个新的元素。然而,它们之间存在一些细微但重要的差别。

push_back()

push_back()函数将一个新的元素插入到向量的末尾,其语法如下:

void push_back(const T& value);

其中,T是向量中元素的类型,value是要插入的元素。

使用push_back()函数时,需要将新元素的值复制到一个临时变量中,然后再将这个变量插入到向量的末尾。这种方法的缺点是,如果T是一个类类型,它的构造函数可能会被调用两次:一次是为了创建临时变量,另一次是为了将它插入到向量中。这会导致性能下降和不必要的开销。

emplace_back()

为了避免这种性能问题,C++11引入了emplace_back()函数。该函数的语法如下:

template <typename... Args>
void emplace_back(Args&&... args);

它可以接受任意数量和类型的参数,并根据这些参数直接在向量的末尾构造一个新的元素。这意味着不需要创建临时变量,也不需要额外的复制操作。

示例

以下代码示例演示了push_back()和emplace_back()的使用:

#include <iostream>
#include <vector>

class Foo
{
public:
    Foo(int x, double y) : x_(x), y_(y) 
    {
        std::cout << "Foo constructor\n";
    }
    
    Foo(const Foo& other) : x_(other.x_), y_(other.y_) 
    {
        std::cout << "Foo copy constructor\n";
    }
    
    ~Foo() 
    {
        std::cout << "Foo destructor\n";
    }
    
private:
    int x_;
    double y_;
};

int main()
{
    std::vector<Foo> v;
    
    // 使用push_back()插入元素
    std::cout << "push_back()\n";
    v.push_back(Foo(1, 2.0));
    
    // 使用emplace_back()插入元素
    std::cout << "emplace_back()\n";
    v.emplace_back(1, 2.0);
    
    return 0;
}

输出结果是:

Foo constructor
Foo copy constructor
Foo destructor
push_back()
Foo constructor
emplace_back()
Foo constructor
Foo destructor
Foo destructor

可以看到,push_back()创建了一个临时的Foo对象,然后将其复制到向量中。而emplace_back()直接在向量中构造了一个新的Foo对象,没有创建任何临时对象。因此,emplace_back()更加高效。

总结
  • push_back()将一个新的元素插入到向量的末尾,但需要创建一个临时对象并将其复制到向量中。
  • emplace_back()直接在向量的末尾构造一个新的元素,没有创建任何临时对象,并且可以接受任意数量和类型的参数。
  • emplace_back()比push_back()更加高效和灵活。

以上就是关于C++ STL向量中的push_back()和emplace_back()的介绍。