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

时间:2014-11-07 04:20:09

标签: c++ swap noexcept

我有以下代码段:

#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,但我不明白为什么。

1 个答案:

答案 0 :(得分:13)

这个重载:

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条)之后和初始化者之前(如果有的话)...

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