为何显式默认移动赋值运算符会导致std::swap编译失败?
问题分析:显式默认移动赋值导致std::swap编译失败
在以下代码中,取消注释移动赋值运算符后,std::swap会导致程序编译失败,GCC、Clang、MSVC三大主流编译器均存在此问题。
#include <utility> #include <memory> struct test { test() = default; test(test&& other) noexcept = default; //test& operator=(test&& other) noexcept = default; test(const test& other) : ptr(std::make_unique<int>(*other.ptr)) {} test& operator=(test other) noexcept { std::swap(*this, other); return *this; } std::unique_ptr<int> ptr; };
核心问题
为何添加显式默认的特殊成员函数会导致标准库无法将该类型视为可移动类型?
问题根源
- 当显式默认移动赋值运算符后,在重载解析时,x值绑定到
T和T&&的优先级相同,引发重载歧义错误。这种歧义会导致标准库中依赖is_move_constructible、is_move_assignable等类型特性的逻辑失效,最终使得std::swap的重载无法正确启用。
重要提示:示例代码并非拷贝交换惯用法的正确实现,应使用自定义swap函数或完整定义5个特殊成员函数,当前实现会导致移动/拷贝赋值与swap调用无限递归。
内容的提问来源于stack exchange,提问作者Xeverous
相关产品推荐
相关产品推荐

