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

C++中结构化绑定接收返回值时std::vector是拷贝还是移动?

问题背景

以下为实现维特比算法的代码:

std::pair<std::vector<index_t>, float> viterbi_get_optimal_path(const SoundGraph &g,
                                                      SequenceIter s_first,
                                                      SequenceIter s_last,
                                                      index_t curr_index) {
  if (s_first == s_last) {
    return {std::vector<index_t>({curr_index}), 1.0f};
  }
  std::vector<index_t> seq;
  float prob = 0.0f;
  for (const auto &[next_index, curr_sound] : g.edges(curr_index)) {
    if (curr_sound.sound_ == *s_first) {
      auto [res_seq, res_prob] =
          viterbi_get_optimal_path(g, std::next(s_first), s_last, next_index);
      if (res_prob > 0.0f && curr_sound.prob_ * res_prob > prob) {
        prob = curr_sound.prob_ * res_prob;
        std::swap(seq, res_seq);
        seq.push_back(curr_index);
      }
    }
  }
  return {seq, prob};
}

补充说明:index_t 是 std::ptrdiff_t 的别名。

核心疑问

请问如下代码行中,函数返回的std::vector<index_t>是发生了拷贝还是移动?

auto [res_seq, res_prob] =
          viterbi_get_optimal_path(g, std::next(s_first), s_last, next_index);

提问者初步判断该vector是被移动的,但无法完全确定。

解答

这里的std::vector<index_t>发生的是移动,不存在拷贝操作,逻辑非常明确:

  • 这行代码用C17引入的结构化绑定接收函数返回的std::pair纯右值,从C17标准开始,纯右值初始化对象时会强制做复制消除,根本不会生成临时的pair对象拷贝,返回的pair会直接在结构化绑定对应的内存位置构造完成,没有额外开销。
  • 再看pair内部的vector:函数最后return {seq, prob};里的seq是函数内部的局部自动存储期变量,完全符合移动构造的触发规则——返回局部同类型对象时,编译器会优先选择vector的移动构造函数来初始化pair的第一个成员,哪怕不做返回值优化(RVO),也绝对不会走拷贝构造逻辑。
  • 最后结构化绑定的res_seq本质就是构造好的pair内部那个vector的别名,绑定过程不会再对vector做任何拷贝或移动操作。

顺便提一句,循环里写的std::swap(seq, res_seq)本身也是基于vector的移动语义实现的,只会交换内部的数据指针、大小、容量三个核心字段,不会把vector存储的索引元素挨个拷贝,开销极低。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 11:33:15