为什么basic_string :: swap不是noexcept?

时间:2013-05-18 22:51:45

标签: c++ c++11

我刚刚发现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则不然。

1 个答案:

答案 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}}。