Std::string not nothrow move可赋值或可比较

std::string not nothrow move assignable or comparable?

本文关键字:赋值 可比较 nothrow string not Std move      更新时间:2023-10-16

我在玩type_traits,我发现了std::string的这个奇怪的性质:

$ cat a.cpp
#include <string>
#include <type_traits>
static_assert(std::is_nothrow_move_assignable<std::string>::value, "???");
static_assert(noexcept(std::declval<std::string>() == std::declval<std::string>()), "???");
$ g++ -std=c++14 a.cpp
a.cpp:4:1: error: static assertion failed: ???
 static_assert(std::is_nothrow_move_assignable<std::string>::value, "???");
 ^
a.cpp:5:1: error: static assertion failed: ???
 static_assert(noexcept(std::declval<std::string>() == std::declval<std::string>()), "???");
 ^
$ g++ --version
g++ (Ubuntu 5.4.0-6ubuntu1~16.04.2) 5.4.0 20160609

然而cppreference声明move赋值操作符和比较操作符被标记为noexcept

我做错了什么吗?这是臭虫吗?

然而cppreference声明移动赋值操作符和比较操作符被标记为noexcept

有一个关于这个的缺陷报告,因为c++ 11说move赋值是noexcept,但这在一般情况下是不可能满足的(因为如果从一个不兼容的分配器移动字符串,它可能需要重新分配)。参见DR 2063。

这个标准已经被修正了,所以异常规范依赖于分配器的属性,但是直到这个新规则在GCC中实现之前,我们没有将这些操作定义为noexcept。我为GCC 6.1实现了固定的规则(请参阅PR 58265),并将更改向后移植到GCC -5分支,但GCC 5还没有发布另一个版本。X从那时起。这个问题将在5.5版本中修复。