21

我有以下片段:

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

4

1 回答 1

13

这个重载:

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

不在范围内 until ;,因此swap(*a, *b)不考虑此重载。这是因为:

3.3.2/1 名称的声明点紧接在其完整声明符之后(第 8 条)和初始化器之前(如果有的话)……</p>

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

于 2014-11-09T15:20:07.647 回答