gpt4 book ai didi

c++ - 为什么 `std:variant` 的 `operator=(T&& t)` 的 noexcept 规范不依赖于内部类型的析构函数的 noexcept 规范?

转载 作者:太空狗 更新时间:2023-10-29 20:20:14 27 4
gpt4 key购买 nike

长标题:为什么 std:variantoperator=(T&& t) 的 noexcept 规范不依赖于内部类型的析构函数的 noexcept 规范?

我可以在 cppreference 上看到那个

template <class T> variant& operator=(T&& t) noexcept(/* see below */);

noexcept(std::is_nothrow_assignable_v<T_j&, T> && 
std::is_nothrow_constructible_v<T_j, T>)

所以编译:

struct FooThrow {
~FooThrow() noexcept(false) {throw;}
};
static_assert(std::is_nothrow_assignable_v<std::variant<FooThrow, int>, int>);

但是它调用了 FooThrow 的析构函数,它是 noexcept(false):

std::variant<FooThrow, int> x;
x = 3; // throws

好像不太对。我错过了什么吗?

最佳答案

一般来说,标准库类型不会友好地接受具有抛出析构函数的类型。或者具体来说,当析构函数实际发出异常时。有一个关于它的一般规则 ( [res.on.functions] )

In certain cases (replacement functions, handler functions, operations on types used to instantiate standard library template components), the C ++ standard library depends on components supplied by a C ++ program. If these components do not meet their requirements, this International Standard places no requirements on the implementation.

In particular, the effects are undefined in the following cases:

...

  • if any replacement function or handler function or destructor operation exits via an exception, unless specifically allowed in the applicable Required behavior: paragraph.

因为 variant::operator= 没有关于抛出析构函数的特殊声明,所以让那些析构函数实际抛出是 UB。

关于c++ - 为什么 `std:variant` 的 `operator=(T&& t)` 的 noexcept 规范不依赖于内部类型的析构函数的 noexcept 规范?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52705879/

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