为什么在C ++ 20中std :: move没有[[nodiscard]]?

时间:2019-04-20 10:07:47

标签: c++ language-lawyer c++17 c++20

我最近阅读了C ++ 17中的[[nodiscard]],据我了解,它是一项新功能(按合同设计吗?),它迫使您使用返回值。对于像std::launder这样的有争议的函数(自C ++ 20起不丢弃),这是有道理的,但是我不知道为什么std::move的定义没有像C ++ 17/20中那样。您知道很好的理由还是因为C ++ 20尚未完成?

2 个答案:

答案 0 :(得分:38)

自VS 2017 15.6起,MSVC标准库团队继续进行工作,并添加了数千个[[nodiscard]]实例,并且报告了该实例的巨大成功(无论是发现大量错误还是没有引起用户投诉)。他们描述的标准大致是:

  1. 纯粹的观察者,例如vector::size()vector::empty甚至std::count_if()
  2. 获取原始资源的东西,例如allocate()
  3. 丢弃返回值的功能极有可能导致错误代码,例如std::remove()

MSVC确实遵循这些标准将std::move()std::forward()都标记为[[nodiscard]]

虽然标准中并未对此进行正式注释,但它似乎可以为用户带来明显的好处,而这更多的是编写这样的论文来标记所有正确的事物[[nodiscard]](同样,来自MSVC的数千个实例) )并应用它们-这本身并不是复杂的工作,但是体积很大。同时,也许是您最喜欢的标准库供应商,并请他们[[nodiscard]]做很多事情?

答案 1 :(得分:30)

AFAIK P0600R1是将[[nodiscard]]添加到已应用于C ++ 20的标准库的唯一建议。从那篇论文:

  

我们建议采取保守的方法:

     

[...]

     

在以下情况下不应添加它:

     
      
  • [...]
  •   
  • 不使用返回值没有意义,但不会造成伤害,并且通常不是错误
  •   
  • [...]
  •   
     

因此,[[nodiscard]]不应发出错误的代码

     
      
  • [...]
  •   
  • 没有受到伤害,而且可能不会发生状态更改,这意味着不会发生
  •   

因此,原因是标准库使用的是保守方法,而尚未提出更具综合性的方法。