You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何C++代码中首个元素会调用拷贝构造函数?

为什么第一个emplace_back会调用拷贝构造函数?

先看你的代码:

#include <iostream>
#include <string>
#include <vector>

struct Vertex
{
    float x, y, z;
    Vertex(float x, float y, float z)
        : x(x), y(y), z(z)
    {
        std::cout << "Created Vertex!" << std::endl;
    }
    Vertex(const Vertex& v) // Copy constructor
        : x(v.x), y(v.y), z(v.z)
    {
        std::cout << "Copied!" << std::endl;
    }
};

std::ostream& operator<<(std::ostream& stream, const Vertex& _v) // Overloading operator<<
{
    stream << _v.x << ", " << _v.y << ", " << _v.z;
    return stream;
}

int main()
{
    std::vector<Vertex> vertices;
    vertices.reserve(3); 
    vertices.emplace_back(Vertex(1, 2, 3)); // 1st assignment
    vertices.emplace_back(4, 5, 6);
    vertices.emplace_back(7, 8, 9);

    return 0;
}

核心原因在于emplace_back的参数传递逻辑:

  • 第一个调用:你手动构造了一个临时Vertex对象Vertex(1,2,3),这会先触发普通构造函数输出"Created Vertex!"。此时emplace_back接收的是一个现成的Vertex实例,它只能把这个临时对象拷贝到vector预留的内存空间里,因此会调用拷贝构造函数输出"Copied!"。
  • 后两个调用:你直接传递了构造Vertex所需的三个float参数。emplace_back的核心能力就是直接在容器的内存区域内,用传入的参数原地构造对象——它会直接调用Vertex(float, float, float)构造函数,不需要先创建临时对象再拷贝,所以只会输出"Created Vertex!",不会触发拷贝构造。

补充:如果给Vertex定义了移动构造函数,第一个调用会触发移动而非拷贝,但因为你没定义移动构造,编译器会 fallback 到拷贝构造。不过本质问题还是你手动创建了临时对象,违背了emplace_back原地构造的设计初衷。

内容的提问来源于stack exchange,提问作者cpp_newbie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 02:45:20