为什么交换多维数组不是例外

Why is swapping multidimensional arrays not noexcept?

本文关键字:数组 交换 为什么      更新时间:2023-10-16

我有以下片段:

#include <algorithm>
#include <iostream>
int main(int argc, char** argv) {
    int x[2][3];
    int y[2][3];
    using std::swap;
    std::cout << noexcept(swap(x, y)) << "n";
    return 0;
}

使用GCC 4.9.0打印0。我不明白为什么。

根据标准,std::swap有两个过载:

namespace std {
    template<class T> void swap(T& a, T& b) noexcept(
        is_nothrow_move_constructible<T>::value &&
        is_nothrow_move_assignable<T>::value
    );
    template<class T, size_t N>
    void swap(T (&a)[N], T (&b)[N]) noexcept(noexcept(swap(*a, *b)));
}

根据我的理解,数组的noexcept说明符应该递归地用于多维数组。

为什么交换多维数组不是noexcept


在试图找到一个仍然表现怪异的最小例子时,我想出了以下方法:

#include <iostream>
template<class T> struct Specialized      : std::false_type {};
template<>        struct Specialized<int> : std::true_type  {};
template<class T>                void f(T& a) noexcept(Specialized<T>::value);
template<class T, std::size_t N> void f(T (&a)[N]) noexcept(noexcept(f(*a)));
int main(int argc, char** argv) {
    int x, y[1], z[1][1];
    std::cout << noexcept(f(x)) << " "
              << noexcept(f(y)) << " "
              << noexcept(f(z)) << "n";
}

使用GCC 4.9.0打印1 1 0,但我也不明白为什么。

此过载:

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

直到;才在作用域中,因此swap(*a, *b)不考虑此过载。这是因为:

3.3.2/1名称的声明点在其完整声明符(第8条)之后,在其初始值设定项(如有)之前…

异常规范是声明器的一部分。