C++14实现std::optional时如何将特殊构造函数移出重载决议
实现方案
你采用的分层继承控制特殊成员函数生成的思路是完全可行的,只需要对optional_move_construct模板增加多维度的特化分支即可覆盖所有要求的场景:
#include <type_traits> // 主模板:对应 T 不可移动构造的场景,完全不声明移动构造函数 template<class T, bool = std::is_move_constructible_v<T>, bool = std::is_trivially_move_constructible_v<T>> class optional_move_construct : public optional_copy_construct<T> { using optional_copy_construct<T>::optional_copy_construct; }; // 特化分支1:T 可移动构造,且为非平凡移动构造 template<class T> class optional_move_construct<T, true, false> : public optional_copy_construct<T> { public: optional_move_construct() = default; optional_move_construct(optional_move_construct&& rhs) noexcept(std::is_nothrow_move_constructible_v<T>) : optional_copy_construct<T>() { if (rhs.m_full) { _impl_construct(std::move(rhs.m_value)); } } optional_move_construct& operator=(optional_move_construct&&) = default; using optional_copy_construct<T>::optional_copy_construct; }; // 特化分支2:T 可平凡移动构造,直接使用编译器生成的平凡移动构造 template<class T> class optional_move_construct<T, true, true> : public optional_copy_construct<T> { public: optional_move_construct() = default; optional_move_construct(optional_move_construct&&) = default; optional_move_construct& operator=(optional_move_construct&&) = default; using optional_copy_construct<T>::optional_copy_construct; };
方案说明
- 当T不可移动构造时,匹配主模板分支,类中没有任何移动构造函数的声明,编译器也不会隐式生成移动构造,自然不会出现在重载决议候选中。此时如果尝试移动optional对象,重载决议会自动匹配复制构造函数(如果T支持复制构造),完全符合C++标准对std::optional的行为要求。
- 当T可平凡移动构造时,匹配第二个特化分支,显式要求编译器生成默认的移动构造,保证移动构造是平凡的。
- 当T可移动构造但非平凡时,匹配第一个特化分支,走手动实现的移动构造逻辑,功能正确。
这个方案完全避开了你之前遇到的两个问题:不需要删除移动构造,不存在被删除的函数参与重载决议的问题;也没有使用模板构造函数,移动构造本身就是非模板的特殊成员函数,优先级符合重载决议规则。
内容的提问来源于stack exchange,提问作者itzjackyscode
相关产品推荐
相关产品推荐

