c++ - C++ 编译器何时为方法推断 noexcept?
问题描述
我只是注意到我的一个std::vector<Foo>
在调整大小时正在复制而不是移动它的元素 - 即使Foo
有一个移动 ctor:
class Foo {
// ...
Foo(Foo&& other) : id_(other.id_), ptr_(other.ptr_), flag(other.flag)
{
other.flag = false;
};
// ...
int id_;
void* ptr_;
bool flag;
}
然后我读到:
这提醒我std::vector
只有在元素的移动 ctor 被声明时才会使用移动构造noexcept
。当我添加时noexcept
,会调用移动 ctor。
我的问题是:为什么考虑到移动 ctor 的代码,编译器不能确定它是noexcept
?我的意思是,它可以知道不能抛出异常的事实。此外,noexcept
标准不允许推断,还是我的特定编译器不做推断?
我在 GNU/Linux 上使用 GCC 5.4.0。
解决方案
tl; dr:不允许编译器推断noexcept
为什么,给定移动 ctor 的代码,编译器不会确定它是 noexcept 吗?
因为 noexcept 规范是根据声明而不是定义确定的。这类似于 const 规范的工作方式。不允许编译器将函数确定为 const,即使它的实现没有修改任何成员。
推断标准不允许的 noexcept
据我了解,是的:
[except.spec] ... 除了析构函数 (12.4) 或释放函数 (3.7.4.2) 之外,函数声明器中没有异常规范表示异常规范是所有类型的集合。
推断除所有类型的集合之外的其他内容将与此规则相矛盾。当然,当编译器可以证明不会抛出异常时,它可以在 as-if 规则下优化掉任何堆栈展开代码,但这样的优化不会影响 SFINAE 自省。
已经讨论过引入 的可能性noexcept(auto)
,这将是让编译器推断 noexcept 规范的一种显式方式。
推荐阅读
- sql - 使用配置单元中的插入覆盖查询更改此合并查询的查询以给出相同的结果
- typescript - rxjs - 观察多个 observables,在任何变化时做出响应
- godot - 线渲染有时不会检测到相交以及如何在循环时使其更宽容
- instagram - 2021年如何通过用户名获取INSTAGRAM图片 - Ruby on Rails
- javascript - 在新创建的输入中自动完成
- java - 如何在 Antlr4 Maven 插件中为组合语法配置 Java 生成的代码(无静态类,无最终方法)?
- c# - 使用 Task.WhenAll 和最大并行度实现并行任务调用时,如何管理锁?
- php - 显示 Woocommerce 属性值描述而不是值名称
- matlab - 图像处理实时瞌睡司机检测matlab
- javascript - 在粘贴大于特定高度的内容后,Quill 在基于 webkit 的浏览器(如 chrome)上滚动到顶部