为什么当T不可移动时,STD ::可选的移动构建体不会被删除
Why is the move-constructor of std::optional not deleted when T is not move-constructible?
根据标准, std::optional<T>
的复制构造人:
...除非
,应将其定义为删除is_copy_constructible_v<T>
是true
。
但是std::optional<T>
的移动结构器:
...除非
,不得参与过载分辨率is_move_constructible_v<T>
是true
。
我了解已删除的构造函数,不删除std::optional<T>
的移动构造符的目的是允许这样的代码:
std::optional<X> o1;
std::optional<X> o2(std::move(o1));
...要依靠某些转换序列工作-o2
将由使用std::optional<X>&&
构建的类型A
对象构造(如果我错了,请纠正我)。
但是,关于std::optional
的可能构造函数,我很难弄清楚可以匹配此用例的构造函数...
为什么std::optional<T>
的移动构建器根本不是如果T
不可移动?
明确删除它意味着它将是最好的匹配X值,从而导致编译时间错误,而不是采用这些案件的复制构造人。
ex:
#include <utility>
struct X
{
X() = default;
X(const X&) = default;
X(X&&) = delete;
};
int main()
{
X a;
X b(std::move(a));
}
这将导致类似:
'X::X(X &&)': attempting to reference a deleted function
明确删除的功能仍然参与超负荷分辨率,可以是最好的匹配。这很有用,例如,禁用某些转换。
委员会真的不在乎可复制但不可移动的憎恶。参见,例如,对LWG问题2768的讨论,该问题的特征是"病理"和以前将其支持为"疯狂"的尝试。
除非有某些特殊原因陷入呼叫(例如,例如,LWG问题2766-但可能会导致不良副作用,否则这种内容的默认措辞通常是"不得参与过载分辨率",除非有某些特殊原因(例如,有时是适当的)例如LWG问题2993)。对于复制特殊成员,根本无法在概念之前完成,因此必须使用"定义为已删除"。对于移动特殊成员,"定义为已删除"的OTOH是不够精确的,因为"明确删除的移动"answers"被隐式定义为已删除的删除"之间存在巨大差异:后者不参与过载分辨率。
另请参见《 LWG问题》第2958页的讨论。
- C++为构建时间获取QDateTime的可靠方法
- 无法在 CLion 中构建 C++ 项目
- 函数向量_指针有不同的原型,我可以构建一个吗
- 如何使用ndk-build.cmd构建Android.so文件
- 将对象移动到std::shared_ptr
- 何时在引用或唯一指针上使用移动语义
- 如何从具有移动语义的类对象中生成共享指针
- libssh 的函数在构建 libssh 时无法在 Qt 和 cmake 错误中找到
- 将shared_ptr移动到<StructA>shared_ptr<变体<结构A、结构 B>>
- C / C++ 移位/偏移/向左或向右移动位图?
- 使用cmake从源代码构建MySQL连接器/C++失败(与以前的声明冲突)
- UNORDERED_MAP的存在确定是否使用了复制构建器或移动构造器
- 有没有一种方法可以在不使用std ::移动的情况下初始化类构建类的类
- 为什么当T不可移动时,STD ::可选的移动构建体不会被删除
- 如何使用常见的C 业务逻辑和数据访问层构建跨平台移动应用程序
- 使用 std::string 参数和不可移动/可复制参数构建 std::map
- Qmake Qt:将头文件移动到构建文件夹
- 为多个移动平台构建工具
- Qt 在构建移动到线程的 QObject 时将"this"作为父传递
- 我如何构建公共数据,同时保留默认的移动元素和分配