递归 noexcept() 是什么意思?

What's the meaning of recursive noexcept()?

标准库定义了数组的交换,std::pair像这样:

template <class T, size_t N>
void swap(T (&a)[N],
          T (&b)[N]) noexcept(noexcept(swap(*a, *b)));

template <class T1, class T2>
struct pair {
    …
    void swap(pair& p) noexcept(noexcept(swap(first,  p.first)) &&
                                noexcept(swap(second, p.second)));
    …
};

有效的现代 C++ 项目 14 说:

[…] whether they are noexcept depends on whether the expression inside the noexcept clauses are noexcept.
Given two arrays of Widget, for example, swapping them is noexcept only if swapping individual elements in the arrays is noexcept, i.e. if swap for Widget is noexcept.
That, in turn, determines whether other swaps, such as the one for arrays of arrays of Widget, are noexcept.
Similarly, whether swapping two std::pair objects containing Widgets is noexcept depends on whether swap for Widgets is noexcept.

但是从这个解释中,我无法理解为什么有必要将调用嵌套为 noexcept(noexcept(swap(*a, *b)))

如果目标是 "swapping two arrays should be as noexcept as swapping elements",为什么 noexcept(swap(*a, *b)) 不够?

这些是 noexcept() 的不同重载还是什么?

这不是 "recursive" noexceptnoexcept 关键字有两种用法:

  • noexcept specifier - 将函数标记为 noexcept 并可选择将 布尔常量表达式 作为参数

  • noexcept operator - 它接受一个 expression 作为参数并且 returns 一个 布尔常量表达式表示表达式是否为noexcept


你的情况:

//          `noexcept` operator
//          v~~~~~~~~~~~~~~~~~~~~~
   noexcept(noexcept(swap(*a, *b)))
// ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// `noexcept` specifier