报错“use of deleted function”是因为代码试图调用被显式(=delete)或隐式删除(如含const/引用成员、定义了移动操作但未定义拷贝)的构造函数或赋值函数,编译器依法阻止非法对象构造。

为什么 use of deleted constructor 会报错
这个错误不是编译器在挑刺,而是你在某处试图调用一个被显式删除(= delete)或隐式删除(比如类里有 const 成员、引用成员、或用户定义了移动操作但没写拷贝构造)的构造函数。编译器发现“你想创建对象”,但“根本没法合法地构造它”,就直接拦下来报错。
常见触发场景包括:把含 const 成员的类对象放进 std::vector、对只允许移动的类型(如 std::unique_ptr)做拷贝初始化、或误传临时对象给需要左值引用的函数参数。
检查类定义里有没有 = delete 或隐式删除的构造函数
打开报错指向的类定义,逐行看构造函数声明:
- 有没有显式写了
MyClass(const MyClass&) = delete;或MyClass(MyClass&&) = delete; - 类里有没有
const int x;或int& ref;这类禁止默认拷贝的成员?有就导致默认拷贝构造函数被隐式删除 - 是否定义了移动构造函数但没定义拷贝构造函数?C++11 起,一旦定义了移动操作,编译器不再自动生成拷贝构造函数
- 基类或成员类的构造函数是否已被删除?子类默认构造函数会尝试调用它们
例如:
struct Bad { const int v = 42; }; —— 此时 Bad b1; Bad b2 = b1; 就会触发该错误,因为 const 成员让默认拷贝构造函数不可用。
怎么绕过或修复这个错误
不能硬加 (T&&) 强转来“骗过”编译器——那只是掩盖问题。真正解法取决于你实际想做什么:
- 如果只是想存对象(比如进容器),改用
std::vector<:unique_ptr>></:unique_ptr>或确保类支持移动语义(加移动构造/赋值,删掉= delete的拷贝函数) - 如果类本就不该被拷贝(如封装了文件句柄),那就别写
obj1 = obj2;,改用指针或引用传递,或显式调用std::move(obj)触发移动(前提是移动构造没被删) - 如果错误来自第三方库类型(如
std::mutex),别试图拷贝它——直接用std::lock_guard<:mutex></:mutex>这类 RAII 类型,它们本身也不可拷贝 - 检查初始化方式:用
{}列表初始化有时能绕过某些隐式转换路径,但不能绕过构造函数被删的本质限制
容易被忽略的关键点
这个错误常出现在模板实例化后才暴露,比如你写了个泛型函数 template<typename t> void foo(T x)</typename>,传入一个不可拷贝的 T,错误信息里可能根本看不到你写的类名,而是显示 STL 内部某处调用了已删除的构造函数。这时候得顺着报错栈往回翻,定位到你第一次把那个类型当作值参数传进去的位置。
另外,std::function、std::thread、std::packaged_task 这些类型都要求可移动(或可拷贝),传入不可移动对象也会引发同类错误,但根源不在你自己的类,而在你传进去的 lambda 或函数对象捕获了不可移动的东西。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











