【发布时间】:2023-03-28 07:35:01
【问题描述】:
在我看来,当移动构造函数为 noexcept(false) 时,标准库必须调用复制构造函数而不是移动构造函数的协议似乎无处不在。
现在我不明白为什么会这样。而且更多的 Visual Studio VC v140 和 gcc v 4.9.2 似乎有不同的做法。
我不明白为什么 noexcept 这是一个问题,例如向量。我的意思是如果 T 没有,vector::resize() 应该如何提供强大的异常保证。如我所见,向量的异常级别将取决于T。无论使用复制还是移动。 我理解 noexcept 只是为了让编译器进行异常处理优化。
这个小程序在使用 gcc 编译时调用复制构造函数,在使用 Visual Studio 编译时调用移动构造函数。
include <iostream>
#include <vector>
struct foo {
foo() {}
// foo( const foo & ) noexcept { std::cout << "copy\n"; }
// foo( foo && ) noexcept { std::cout << "move\n"; }
foo( const foo & ) { std::cout << "copy\n"; }
foo( foo && ) { std::cout << "move\n"; }
~foo() noexcept {}
};
int main() {
std::vector< foo > v;
for ( int i = 0; i < 3; ++i ) v.emplace_back();
}
【问题讨论】:
-
通过在重新分配期间复制vector的元素,您可以保持以前的存储不变;通过移动它们,它会被修改。如果抛出异常,则无法撤消,因为可能会抛出另一个异常