【问题标题】:Prevent passing temporary for const ref parameter防止为 const ref 参数传递临时参数
【发布时间】:2016-11-24 15:33:32
【问题描述】:

我有一个函数:

void AddImage(const Image &im);

这个函数不需要图像是可修改的,但是它将图像存储为一个常量引用以供以后使用。因此,这个函数不应该允许临时的。在没有任何预防措施的情况下,以下工作:

Image GetImage();

...

AddImage(GetImage());

有没有办法阻止这个函数调用?

【问题讨论】:

  • 除了眼前的问题还要考虑生命周期的问题。在您当前的设计中,调用者负责确保图像在被调用者可以使用的情况下一直存在。像这样的不对称所有权可能会导致严重的问题。如果没有更多上下文,我不能说您的代码是否属于这种情况。这绝对是需要小心谨慎的事情。
  • 绝对正确。然而,这是对工作系统的过度简化。在工作系统中 AddImage 是动画对象的成员函数,图像和动画对象的生命周期是同步的(它们通常是同一类的成员)。为了确保销毁序列不会出现任何问题,动画在销毁过程中不会检查其子项。

标签: c++ reference constants


【解决方案1】:

有几种机制可以防止将临时参数传递给 const ref 参数。

  1. 删除带右值参数的重载:void AddImage(const Image &&) = delete;

  2. 使用 const 指针:void AddImage(const Image*)。此方法适用于 C++11 之前的版本

  3. 使用引用包装器:void AddImage(std::reference_wrapper<const Image>)

使用支持 C++11 的编译器时,应首选第一种方法。它使意图明确。第二种方法需要nullptr 的运行时检查,并且没有传达图像不能为空的想法。第三种方法有效,意图明确,但过于明确。

【讨论】:

  • 现在我可以在编译时检测到传递临时文件的问题。非常感谢!
  • 如果您能详细说明std::reference_wrapper 在这种情况下的工作原理,我将不胜感激。如果参数是临时 obj std::string,并且函数返回指向其 .data() 的指针,会发生什么情况?在这种情况下会起作用吗?
  • 我认为(不确定)第三个选项使用删除了 r 值重载的构造函数。因此它将防止临时作为参考传递。
  • 请注意,如果您有多个 const 引用参数需要防止传递临时变量,则选项 1 需要线性(或指数,如果您想避免歧义)许多重载。
  • 第三种方法“过于露骨”是什么意思?
猜你喜欢
  • 2018-01-20
  • 2015-10-02
  • 1970-01-01
  • 2021-12-14
  • 2019-12-28
  • 1970-01-01
  • 2012-02-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多