我有以下代码段:
#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
,但我不明白为什么。
答案 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条)之后和初始化者之前(如果有的话)...
,异常规范是声明者的一部分。