为何Clang认为我的结构体存在拷贝构造函数?
显式删除拷贝构造函数后仍触发Clang-Tidy特殊成员函数检查
代码示例
struct MyStruct { MyStruct(MyStruct& other) = delete; MyStruct(MyStruct&& other) = default; explicit MyStruct(int num) noexcept(false); explicit MyStruct(MyOtherStructType&& other_type); ~MyStruct(); auto operator=(MyStruct&& other) noexcept(false) -> MyStruct&; };
Clang-Tidy提示
Class 'MyStruct' defines a non-default destructor, a copy constructor, a move constructor and a move assignment operator but does not define a copy assignment operator
用户疑问
明明已删除拷贝构造函数,是否遗漏了什么?该检查规则是否有误?
解答
这个提示不是误报,核心原因是hicpp-special-member-functions/cppcoreguidelines-special-member-functions规则严格遵循C++的「特殊成员函数一致性」要求:当你显式定义/删除任意一个特殊成员函数(析构、拷贝构造、拷贝赋值、移动构造、移动赋值),就需要显式处理所有相关的特殊成员函数,不能依赖编译器的隐式推导。
你的代码中:
- 显式删除了拷贝构造函数
- 默认了移动构造函数
- 自定义了析构函数
- 自定义了移动赋值运算符
但没有显式声明拷贝赋值运算符的状态——哪怕编译器会因为你删除拷贝构造函数而隐式删除拷贝赋值,规则依然要求你显式写出删除语句,以此明确代码意图,避免阅读者需要推导编译器的隐式行为。
解决方法
在结构体中添加显式删除的拷贝赋值运算符即可消除提示:
// 标准签名的拷贝赋值删除 auto operator=(const MyStruct&) -> MyStruct& = delete;
另外补充一点:你的拷贝构造函数签名MyStruct(MyStruct& other)不符合C++常规规范,标准的拷贝构造函数应该接受const MyStruct&类型的参数,建议修正这个签名,避免引发其他潜在问题。
内容的提问来源于stack exchange,提问作者Camden Narzt
相关产品推荐
相关产品推荐

