ein*_*ica 4 c++ gcc compiler-optimization move-constructor 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;
}
Run Code Online (Sandbox Code Playgroud)
然后我读到:
这提醒我,std::vector只有在声明了元素的移动构造函数时才会使用移动构造noexcept。当我添加时noexcept,会调用移动 ctor。
我的问题是:为什么,给定移动 ctor 的代码,编译器没有确定它是noexcept?我的意思是,它可以知道不能抛出异常的事实。此外,推断是否noexcept被标准禁止,或者不是由我的特定编译器完成的?
我在 GNU/Linux 上使用 GCC 5.4.0。
noexcept为什么,给定移动 ctor 的代码,编译器没有确定它是 noexcept 吗?
因为 noexcept 规范是基于声明而不是定义确定的。这类似于 const 规范的工作方式。即使其实现不修改任何成员,编译器也不允许将函数确定为 const。
正在推断标准不允许的 noexcept
据我了解,是的:
[except.spec] ...在除析构函数 (12.4) 或解除分配函数 (3.7.4.2) 之外的函数声明器中缺少异常规范表示异常规范是所有类型的集合。
推断除所有类型的集合之外的其他内容将与此规则相矛盾。当然,当编译器能够证明不会抛出异常时,它可以优化掉任何在 as-if 规则下的堆栈展开代码,但这种优化不会影响 SFINAE 内省。
已经讨论了引入 的可能性noexcept(auto),这将是让编译器推断 noexcept 规范的明确方式。