我刚刚发现basic_string的两个交换函数(命名空间std中的成员函数和函数)没有用 noexcept 声明 - 既不是在GCC-4.8的标准库中也不是在最近的标准库中C ++草案N3690。
另一方面,移动构造函数以及移动赋值运算符使用 noexcept 声明。这表明应该可以提供 noexcept 交换功能。
问题:没有使用 noexcept 声明交换函数的原因是什么?
更新:问题是我想在我自己的交换函数中使用模板函数,它使用static_assert检查交换实际上是 noexcept ,例如:
struct foo {
bar_t bar;
baz_t baz;
void swap(foo& rhs) noexcept {
swap_noexcept(bar, rhs.bar);
swap_noexcept(baz, rhs.baz);
}
};
但是,仅当使用 noexcept 声明交换函数时才有效,而basic_string
则不然。
答案 0 :(得分:19)
C ++ 11标准的第21.4.6.8段规定:
21.4.6.8
basic_string::swap
[string :: swap]void swap(basic_string& s);
1 后置条件:*这包含与s中相同的字符序列,s包含相同的字符序列 在* this中的字符序列。
2 投掷:没什么。
3 复杂性:恒定时间。
因此,必须得出结论,noexcept
的缺席是一种疏忽。
关于assign()
成员函数的第21.4.6.3段给出了另一条线索:
basic_string& assign(basic_string&& str) noexcept;
效果:该函数将
*this
控制的字符串替换为长度为str.size()
的字符串,其长度为str
元素是由swap(str)
控制的字符串的副本。 [注意:有效的实施是*this.
。 - 结束说明]3 返回:
swap(str)
如果assign()
应该是assign()
的有效实施,并且noexcept
被标记为无条件swap()
,那么假设noexcept
是有意义的也是{{1}}。