gpt4 book ai didi

c++ - vector::push_back 使用 std::move 进行内部重新分配

转载 作者:行者123 更新时间:2023-12-05 04:35:19 24 4
gpt4 key购买 nike

A型X有一个非平凡的 move 构造函数,声明为 noexcept(即它可以抛出):

#include <iostream>
#include <vector>
#include <memory>


struct X {
X()=default;
X(X&&) { std::cout << "X move constructed\n"; } // not 'noexcept'
X(const X&) { std::cout << "X copy constructed\n"; }
};

struct test {
X x;
};

int main()
{
static_assert(std::is_nothrow_move_constructible_v<X> == false);
static_assert(std::is_nothrow_move_constructible_v<test> == false);

std::vector<test> v(1);
v.push_back(test{}); // internal object re-allocation, uses copy-constructor
}

调用push_back时在 vector<test> 上,内部重新分配导致现有对象被复制,这是预期的。输出是:

X move constructed
X copy constructed

显然,第二行与内部对象重新分配有关。

现在是不相关的 std::unique_ptr<int>添加到 test :

struct test {
std::unique_ptr<int> up;
X x;
};

输出变为:

X move constructed
X move constructed

为什么这次内部重新分配使用 move 构造函数?
从技术上讲,X(X&&)仍然可以抛出异常;这不会违反 push_back 的强异常保证吗? ?

编译器是 gcc 11.2.1 和/或 clang 12.0.1

最佳答案

根据 [vector.modifiers]/2如果 std::vector 的元素类型不可复制插入且不可抛出 move 构造,则从该元素类型的 move 构造函数抛出的异常会导致容器处于未指定状态。

std::vector 如果类型不是不可 move 的,则必须优先使用复制构造函数,以便可以保留异常保证,但如果不可能,则不可能提供强有力的异常保证。

关于c++ - vector::push_back 使用 std::move 进行内部重新分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71053575/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com