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

关于构造函数初始化列表中使用std::move的clang-tidy建议疑问

关于构造函数初始化列表中使用std::move的clang-tidy建议疑问

嘿,我最近碰到clang-tidy的一个建议有点懵,想跟大伙唠唠这个事儿。clang-tidy给我的提示是:

Clang-tidy: arg is passed by value and only used once; consider moving it.

我的代码大概是这样的:

struct S{
    kinda_heavy obj;
    S(kinda_heavy heavy):obj(heavy){}
    void do_stuff();
};

我本来是期望调用者会传入一个x值参数的,比如像这样:

S app = S(get_kinda_heavy());

或者调用者也可能用左值来构造,但我一开始觉得临时对象传进来的时候已经是移动构造参数了,直接初始化obj应该没问题啊,为啥clang-tidy要让我用move呢?

其实仔细琢磨一下就明白啦,clang-tidy的建议真的很有道理:

  • 当调用者传临时对象(x值)时,参数heavy确实是通过移动构造来的,但在初始化列表里直接写obj(heavy),会触发拷贝构造把heavy的内容复制给obj——因为heavy在这里是左值,编译器不会自动帮你移动它。
  • 如果改成obj(std::move(heavy)),就能把heavy里的资源直接移动给obj,完全省去了这次不必要的拷贝开销,毕竟heavy在构造函数里只用这一次,用完就销毁了,移动完全安全。

那如果调用者传的是左值呢?比如kinda_heavy h; S s(h);,这时候参数heavy是拷贝构造来的,之后再移动给obj,对比原来的两次拷贝(拷贝参数+拷贝初始化),变成了一次拷贝+一次移动,而移动的开销通常比拷贝小得多,所以不管调用者传左值还是右值,改成move都是更优的选择。

所以听clang-tidy的准没错,把构造函数改成S(kinda_heavy heavy):obj(std::move(heavy)){}就好啦,既能优化右值传入的场景,也能降低左值传入的开销。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.08 13:43:10