Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/144.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么是'std:variant'';s`operator=(T&;T)`x27;s无异常规范不';t依赖于内部类型';s析构函数&x27;这不例外吗?_C++_Variant_Nothrow_Std Variant - Fatal编程技术网

C++ 为什么是'std:variant'';s`operator=(T&;T)`x27;s无异常规范不';t依赖于内部类型';s析构函数&x27;这不例外吗?

C++ 为什么是'std:variant'';s`operator=(T&;T)`x27;s无异常规范不';t依赖于内部类型';s析构函数&x27;这不例外吗?,c++,variant,nothrow,std-variant,C++,Variant,Nothrow,Std Variant,长标题:为什么std:variant的操作符=(T&&T)的noexcept规范不依赖于内部类型的析构函数的noexcept规范 我可以在上面看到 这似乎不对。我遗漏了什么吗?一般来说,标准库类型不喜欢使用抛出析构函数的类型。或者具体地说,当析构函数实际发出异常时。关于它有一个一般的规则() 在某些情况下(替换函数、处理函数、用于实例化标准库模板组件的类型操作),C++标准库依赖于C++程序提供的组件。如果这些组件不符合其要求,则本国际标准对实施无任何要求 特别是,在以下情况下,影响未定义:

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

我可以在上面看到


这似乎不对。我遗漏了什么吗?

一般来说,标准库类型不喜欢使用抛出析构函数的类型。或者具体地说,当析构函数实际发出异常时。关于它有一个一般的规则()

在某些情况下(替换函数、处理函数、用于实例化标准库模板组件的类型操作),C++标准库依赖于C++程序提供的组件。如果这些组件不符合其要求,则本国际标准对实施无任何要求

特别是,在以下情况下,影响未定义:

  • 如果任何替换函数、处理函数或析构函数操作通过异常退出,除非适用的必需行为:段落中明确允许

由于
variant::operator=
没有关于抛出析构函数的特殊语句,因此让这些析构函数实际抛出是UB。

“但它调用FooThrow的析构函数”where?在编译时无法检查使用的是哪种类型以及分配给的是哪种类型。因此,如果任何类型都有抛出析构函数,那么唯一的选择就是不允许赋值,这将是不好的。否则它将如何破坏现有的值呢?记住,选择的类型可能会改变。我添加了一个简单的示例。
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>);
std::variant<FooThrow, int> x;
x = 3; // throws