c++ - 为什么`std::optional::operator=` 当 T 包含 `const` 数据成员时删除?
问题描述
以下代码会导致编译器错误:
#include <optional>
class A {
};
class B {
private:
const A a;
};
int main()
{
B b;
std::optional<B> bo1;
bo1 = b;
}
例如,在 gcc 上,错误显示为:
main.cpp: In function 'int main()':
main.cpp:12:7: error: uninitialized const member in 'class B'
12 | B b;
| ^
main.cpp:7:13: note: 'const A B::a' should be initialized
7 | const A a;
| ^
main.cpp:14:11: error: use of deleted function 'std::optional<B>& std::optional<B>::operator=(std::optional<B>&&)'
14 | bo1 = b;
| ^
In file included from main.cpp:1:
/lib/gcc-head/include/c++/12.0.0/optional:663:11: note: 'std::optional<B>& std::optional<B>::operator=(std::optional<B>&&)' is implicitly deleted because the default definition would be ill-formed:
663 | class optional
| ^~~~~~~~
/lib/gcc-head/include/c++/12.0.0/optional:663:11: error: use of deleted function 'std::_Enable_copy_move<true, false, true, false, _Tag>& std::_Enable_copy_move<true, false, true, false, _Tag>::operator=(std::_Enable_copy_move<true, false, true, false, _Tag>&&) [with _Tag = std::optional<B>]'
In file included from /lib/gcc-head/include/c++/12.0.0/optional:43,
from main.cpp:1:
/lib/gcc-head/include/c++/12.0.0/bits/enable_special_members.h:248:5: note: declared here
248 | operator=(_Enable_copy_move&&) noexcept = delete;
| ^~~~~~~~
在 MSVC 上,作为另一个示例,错误显示为:
main.cpp
<source>(14): error C2280: 'std::optional<B> &std::optional<B>::operator =(const std::optional<B> &)': attempting to reference a deleted function
C:/data/msvc/14.29.29917-Pre/include\optional(445): note: compiler has generated 'std::optional<B>::operator =' here
C:/data/msvc/14.29.29917-Pre/include\optional(445): note: 'std::optional<B> &std::optional<B>::operator =(const std::optional<B> &)': function was implicitly deleted because a base class invokes a deleted or inaccessible function 'std::_Deleted_move_assign<std::_Optional_construct_base<_Ty>,_Ty> &std::_Deleted_move_assign<std::_Optional_construct_base<_Ty>,_Ty>::operator =(const std::_Deleted_move_assign<std::_Optional_construct_base<_Ty>,_Ty> &)'
with
[
_Ty=B
]
C:/data/msvc/14.29.29917-Pre/include\xsmf_control.h(131): note: 'std::_Deleted_move_assign<std::_Optional_construct_base<_Ty>,_Ty> &std::_Deleted_move_assign<std::_Optional_construct_base<_Ty>,_Ty>::operator =(const std::_Deleted_move_assign<std::_Optional_construct_base<_Ty>,_Ty> &)': function was implicitly deleted because a base class invokes a deleted or inaccessible function 'std::_Deleted_copy_assign<std::_Optional_construct_base<_Ty>,_Ty> &std::_Deleted_copy_assign<std::_Optional_construct_base<_Ty>,_Ty>::operator =(const std::_Deleted_copy_assign<std::_Optional_construct_base<_Ty>,_Ty> &)'
with
[
_Ty=B
]
C:/data/msvc/14.29.29917-Pre/include\xsmf_control.h(92): note: 'std::_Deleted_copy_assign<std::_Optional_construct_base<_Ty>,_Ty> &std::_Deleted_copy_assign<std::_Optional_construct_base<_Ty>,_Ty>::operator =(const std::_Deleted_copy_assign<std::_Optional_construct_base<_Ty>,_Ty> &)': function was explicitly deleted
with
[
_Ty=B
]
Compiler returned: 2
只要我们删除const
关键字 in const A a;
,错误就会消失。根据std::optional 上的引用标准,在某些情况下 = 运算符的某些重载将被删除,具体取决于 std::is_...able_v 测试。在这种情况下,为什么const
关键字会影响其中一些测试?
解决方案
optional
使用对象的=
.
const
不能将具有数据成员的类分配给。它只能被构建。
试试这个:
B b0;
B b1;
b0=b1;
optional
不起作用,因为B
没有。
另外, try static_assert(!std::is_copy_assignable_v<B>);
,它通过了。
现在,std::optional
这里有一个“后门”。
B b;
std::optional<B> bo1;
bo1.emplace(b);
它构造而不是分配。
理论上,可选可以依赖于此;但如果内容存在,则需要将其销毁,然后放置一个新对象。这是有风险的,会打乱语义,并且是一个糟糕的静默计划。
推荐阅读
- javascript - 无法执行重定向 302
- mysql - 无法对单个表使用子查询 sql
- maven - 如何使用 maven 从 WEB-INF 类文件夹中删除 etc 文件夹?
- python - Anaconda 安装 TensorFlow 1.15 而不是 2.0
- html - 在 React-Native 中从 API 解析 HTML 字符串?
- sql - 如何通过先前记录的子字符串连接分层查询
- sum - 是否可以在 FFT 算法中使用负指数?
- r - R中是否有一个函数可以在考虑到最终目标的情况下进行预测?
- angular - 如何找到触发 ngZone 的异步操作(导致更改检测)?
- c++ - 如何通过 g++ 从 OpenACC C++ 代码中调用 cuda 库?