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

为何默认拷贝构造函数添加explicit会导致无法返回对象?

问题原因解析:explicit构造函数导致返回值编译失败

问题场景

以下是最小可复现示例:

class A {
public:
    A() = default;
    explicit A(const A&) = default;
    // explicit A(A&) = default; ///添加这个没有作用
    explicit A(A&&) = default;
    A& operator=(const A&) = default;
    A& operator=(A&&) = default;
};

auto dummy_a() {
    A a;
    return a; //报错:no matching function for call to 'A::A(A)'
}

int main() {
    const auto a = dummy_a();
}

编译上述代码会出现如下错误,除非移除拷贝构造函数或移动构造函数的explicit关键字:

main.cpp: In function 'auto dummy_a()':
main.cpp:14:12: error: no matching function for call to 'A::A(A)'
   14 |     return a; //no matching function for call to 'A::A(A)'
      |            ^
main.cpp:4:5: note: candidate: 'constexpr A::A()'
    4 |     A() = default;
      |     ^
main.cpp:4:5: note:   candidate expects 0 arguments, 1 provided

原因分析

  • 执行return a;时,编译器需要将局部变量a转换为函数返回值类型(即A),这个过程依赖拷贝构造函数或移动构造函数来创建返回对象。
  • explicit关键字的作用是限制构造函数只能用于显式类型转换,禁止编译器隐式调用它。你给拷贝构造函数(explicit A(const A&))和移动构造函数(explicit A(A&&))都加了这个限制,导致编译器无法在返回值的场景中隐式调用它们。
  • 即使编译器可能会做返回值优化(RVO)来避免实际的拷贝/移动操作,C++标准仍然要求对应的构造函数必须是可隐式调用的,否则编译无法通过。
  • 错误提示中提到的A::A(A)是编译器尝试寻找的非const左值引用拷贝构造函数,但你并未定义它;而你定义的const左值和右值版本都是explicit的,无法被隐式调用,最终编译器找不到可用的构造函数,因此报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 04:46:11