Std::string not nothrow move可赋值或可比较
std::string not nothrow move assignable or comparable?
我在玩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版本中修复。
相关文章:
- 使用重载 [] 运算符返回 std::map() 的可赋值
- std::constexpr 上下文中的可选赋值运算符
- 可视化的c++变量赋值使代码正常工作
- const变量是否可以在具有默认值的参数中赋值(作为可选参数)
- 具有抑制移动构造/赋值的类型如何仍被视为可移动类型?
- C++复制可克隆层次结构中的构造函数和赋值
- 循环赋值的多维数组:表达式必须是可修改的左值
- 可以错误地使用赋值运算符而不是比较运算符的地方,= Vs ==
- C++ 带有指针、赋值和比较的结构
- 带有模板类的赋值运算符 - 没有可接受的转换,C++
- 有没有一种方法可以使用std::array与文字或初始值设定项列表进行比较,就像使用赋值一样
- C++与赋值表达式的比较是右侧表达式
- 为什么具有const成员的结构是可赋值的
- 在不使用元素复制赋值运算符的情况下复制向量 - 可移植性
- 比较 (<)、输出 (<<) 和赋值 (=) 用于提升::可选
- 返回的对象如何可赋值
- boost可选赋值和std::experimental可选赋值的区别
- 在可强制转换为另一个模板类型的类模板中重载赋值操作符
- Std::string not nothrow move可赋值或可比较
- c++复制赋值语法比较-哪个更好