显式删除移动构造后,类为何不满足std::is_move_constructible?
问题解答
核心原因是重载决议的优先级规则,以及显式删除移动构造函数对重载候选集的影响:
当你没声明任何移动构造函数时,编译器不会生成移动构造(因为你已定义了拷贝构造),此时用右值构造对象会 fallback 到匹配
const T&的拷贝构造函数——右值可以绑定到const左值引用,构造合法,std::is_move_constructible自然返回true。但一旦你显式删除移动构造函数(
T(T&&) = delete;),这个函数就会进入重载候选集。当用右值构造对象时,编译器会优先匹配参数为T&&的移动构造函数(右值和T&&的匹配度比const T&更高),而这个函数是被删除的,直接导致构造操作非法,所以std::is_move_constructible断言失败。
举个代码例子直观说明:
#include <type_traits> class A { public: A(const A&) {} // 用户定义拷贝构造 // 无移动构造声明 }; class B { public: B(const B&) {} B(B&&) = delete; // 显式删除移动构造 }; // 编译通过:右值可绑定到const A&,调用拷贝构造 static_assert(std::is_move_constructible_v<A>); // 编译失败:优先匹配被删除的B(B&&),构造非法 static_assert(std::is_move_constructible_v<B>);
简单说,显式删除移动构造相当于在重载候选里放了一个“无效的优先选项”,编译器会先选它,直接导致整个构造操作不可行,不会再尝试后面的拷贝构造。
内容的提问来源于stack exchange,提问作者Jimbo
相关产品推荐
相关产品推荐

