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

为何满足条件却未隐式声明拷贝/移动构造函数?

为什么我的类C没有隐式生成拷贝/移动构造函数?

这个问题核心在于C++标准里特殊成员函数隐式生成的抑制规则,咱们一步步拆解清楚:

1. 移动构造函数的隐式生成限制

C++11及以后的标准规定:如果你的类显式声明了以下任意一个特殊成员函数,编译器会禁止隐式生成移动构造函数和移动赋值运算符:

  • 自定义析构函数(~C())
  • 显式声明的拷贝构造函数(C(const C&))
  • 显式声明的拷贝赋值运算符(C& operator=(const C&))

这是为了兼容旧代码:很多老代码会自定义析构函数,但没考虑移动语义,编译器如果自动生成移动构造,可能会导致意外的资源错误,所以干脆直接抑制。

2. 拷贝构造函数的隐式生成限制

反过来,如果你的类显式声明了移动构造函数或移动赋值运算符,编译器会禁止隐式生成拷贝构造函数和拷贝赋值运算符。

3. 结合你的场景分析

你的类C大概率是显式声明了上述会触发抑制的成员函数(比如自定义析构函数),导致编译器没有隐式生成移动构造。而std::is_invocable_r在内部检查时,刚好需要用到这个移动构造函数,所以才会在gcc7.3和clang5.0.1里编译失败。

当你取消注释移动构造函数(比如用= default显式默认它),这个构造函数就被明确生成了,std::is_invocable_r的检查通过,自然就能编译了。

举个实际的例子,你的类可能是这样的:

class C {
public:
    // 显式声明析构函数,直接抑制移动构造的隐式生成
    ~C() { /* 自定义析构逻辑 */ }

    // 取消注释后,显式默认移动构造,编译器生成它
    // C(C&&) = default; // (1)
};

4. 你觉得“满足隐式声明要求”的误区

你可能忽略了类中存在的其他显式声明的特殊成员函数(比如析构),这些函数是触发抑制规则的关键。哪怕你的类所有数据成员都支持移动,只要有这些显式声明,编译器就不会隐式生成移动构造。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 10:06:27