【发布时间】:2015-01-03 19:35:01
【问题描述】:
我有以下sn-p:
#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,但我还是不明白为什么。
【问题讨论】:
-
对我来说似乎很奇怪。我在 libstdc++ 中发现 DR 809 其中 appears 是 implemented 所以这个 bug 可能在别处。根据您的最新编辑,clang 也会打印出
1 1 0。用 libc++ 打印0为原始的 sn-p。 -
在通过调试器运行它后,对于 libstdc++,它会经历
std::swap和std::move的重载,标记为 noexcept。 clang 和 g++ 对完全相同的库代码有不同的结果这一事实让我大吃一惊。请注意,noexcept甚至不会生成std::swap的代码。