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

C++使用emplace_back向vector插入C类对象传参报错如何解决

错误根因

std::vector::emplace_back 是变长模板函数,依赖模板实参推导匹配传入参数和目标类型构造函数的参数列表。不带类型标识的花括号初始化列表{std::make_shared<A>(), 2}没有明确类型,无法被模板推导,因此第一种写法直接编译失败。
你给出的第二种写法显式构造了临时B对象,不符合emplace_back原地构造的设计目标,且注意你当前定义的C构造函数第一个参数为std::vector<B>,这种写法也会因为参数类型不匹配编译失败。

解法(分两种场景匹配你的实际需求)

场景1:C的构造函数定义正确,第一个参数为std::vector<B>

你需要先构造符合要求的std::vector<B>,再传递给C的构造函数,全程无多余开销的写法如下:

std::vector<C> vecC;
// 先原地构造vector<B>,再移动给C的构造函数,vector的移动操作无额外内存拷贝开销
std::vector<B> tmp_vec;
tmp_vec.reserve(1);
tmp_vec.emplace_back(std::make_shared<A>(), 2);
vecC.emplace_back(std::move(tmp_vec), false);

如果可以接受极少量的B对象移动开销,也可以简化写法:

vecC.emplace_back(std::initializer_list<B>{{std::make_shared<A>(), 2}}, false);

场景2:C的构造函数为笔误,第一个参数实际为B

这种场景下可以通过新增完美转发构造函数实现完全原地构造,无任何临时对象生成:

// 修改C的定义,新增完美转发构造
struct C
{
    // 原有构造保留,新增以下构造函数
    template<typename... Args, typename = std::enable_if_t<std::is_constructible_v<B, Args...>>>
    C(Args&&... b_args, bool c): v_(std::forward<Args>(b_args)...), c_(c) {}

    B v_;
    bool c_;
};

// 调用代码,直接传递B的构造参数即可
std::vector<C> vecC;
vecC.emplace_back(std::make_shared<A>(), 2, false);

如果不想修改C的定义,显式构造B临时对象的写法实际开销极低,因为B的移动构造是轻量化的,绝大多数场景下性能完全符合要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 14:18:02