为什么 std::move 在 C++20 中不是 [[nodiscard]]?
Why is std::move not [[nodiscard]] in C++20?
我最近在 C++17 中读到了[[nodiscard]]
,据我所知,这是一个新功能(合同设计?),它迫使你使用返回值。这对于像std::launder
这样的有争议的函数是有意义的(自 C++20 年以来的 nodiscard),但我想知道为什么std::move
在 C++17/20 中没有这样定义。你知道一个很好的理由还是因为C++20尚未最终确定?
自VS 2017 15.6以来,MSVC标准库团队继续添加数千个[[nodiscard]]
实例,并报告了它的巨大成功(无论是在发现大量错误方面还是在未产生用户投诉方面)。他们描述的标准大致是:
- 纯观察者,例如
vector::size()
、vector::empty
,甚至std::count_if()
- 获取原始资源的事物,例如
allocate()
- 丢弃返回值极有可能导致错误代码的函数,例如
std::remove()
MSVC 确实按照这些标准将std::move()
和std::forward()
标记为[[nodiscard]]
。
虽然它没有在标准中正式注释,但它似乎提供了明显的用户利益,更多的是制作这样一篇论文来标记所有正确的东西[[nodiscard]]
(再次,来自 MSVC 的数千个实例)并应用它们——它本身并不复杂,但体积很大。与此同时,也许可以刺激您最喜欢的标准库供应商并要求他们[[nodiscard]]
很多东西?
AFAIK P0600R1 是将[[nodiscard]]
添加到应用于 C++20 的标准库中的唯一建议。从那篇论文:
我们建议采取保守的方法:
[...]
在以下情况下不应添加它:
- [...]
- 不使用返回值没有意义,但不会造成伤害,通常不是错误
- [...]
因此,如果出现这种情况,[[nodiscard]] 不应该发出错误代码的信号
- [...]
不会- 造成伤害,并且可能没有状态更改意味着不会发生
所以原因是标准库使用了一种保守的方法,而还没有提出更激进的方法。
相关文章:
- 使用std::multimap迭代器创建std::list
- C++中std::resize(n)和std::shrink_to_fit之间的区别
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 如何导出包含具有"std::unique_ptr"值的"std::map"属性的
- 从持续时间构造std::chrono::system_clock::time_point
- std::具有相同基类的类的变体
- std::向量与传递值的动态数组
- 使用std::vector的OpenCL矩阵乘法
- std::map<struct,struct>::find 找不到匹配项,但是如果我循环通过 begin() 到 end(),我在那里看到匹配项
- std::condition_variable::wait()如何评估给定的谓词
- 如何获取std::result_of函数的返回类型
- std::原子加载和存储都需要吗
- 将对象移动到std::shared_ptr
- POCO::PostgreSQL:如何将std::vector支持添加到`Binder::bind`
- 使用一个考虑到std::map中键值的滚动或换行的键
- 如何从 std::atomic 中提取指针 T<T>?
- 为什么 std::unique 不调用 std::sort?
- 使用std::函数映射对象方法
- 为什么 std::move 在 C++20 中不是 [[nodiscard]]?