【问题标题】:Avoid const locals that are returned?避免返回的 const locals?
【发布时间】:2016-11-06 14:36:10
【问题描述】:

我一直认为 const locals 是 const 是件好事

void f() {
    const resource_ptr p = get();
    // ...
}

然而,上周我看到学生在做 C++ 练习并且想知道返回的 const 指针

resource_ptr f() {
    const resource_ptr p = get();
    // ...
    return p;
}

在这里,如果编译器无法应用 NRVO(想象在某些情况下这是正确的,可能会返回两个指针之一,具体取决于条件),const 突然变得悲观,因为编译器不能从p 移动,因为它是常量。

在返回的本地人上尝试避免const 是个好主意,还是有更好的方法来处理这个问题?

【问题讨论】:

  • 不能通过 as-if 规则从 const 本地移动吗?
  • 在实践中,编译器在应用 (N)RVO 方面往往很糟糕,除了最微不足道的情况外,因此这是一个合理的担忧。一个特殊情况是当您的“局部变量”实际上是一个参数时,可悲的是禁止复制省略。
  • @Pixelchemist 这就是它的作用。它有效地在它周围放置了一个std::move(..)。但是p 是常量,所以它不会离开它。
  • 如果你的类型有一个复制构造函数Type(Type const&&),它将使用它。大多数人认为在这样的构造函数中修改参数是错误的(它是const),但并非全部,有些人认为它是一个右值更重要。无论如何,我个人避免在此类变量上使用const
  • @juanchopanza 规范允许,但 impl 做不到

标签: c++ c++14 move-semantics nrvo


【解决方案1】:

在返回的本地人上尝试避免const 是个好主意,还是有更好的方法来处理这个问题?

是的。事实上,如果 resource_ptr 是一个 move-only 类型,如果你尝试返回 const,你会得到一个编译时错误。

这是“经过验证的”C++98/03 建议不再适用于 C++11 及更高版本的示例。

【讨论】:

  • 这里有强制省略(C++17)改变的情况吗?
  • @MarcGlisse:我自己还在学习新的 C++17 规则。但我目前的理解是强制省略仅适用于返回未命名临时的情况。例如:return X{};.
  • @HowardHinnant 将规则使p const 直到return 语句不会更好,如果在return 之后没有其他对p 的引用(声明的本地人的dtors在p) 之后?返回将忽略const。我不喜欢这些每隔一行代码就等着你的“陷阱”。
  • @HowardHinnant 我还没有阅读新规则,感谢您的快速解释。
  • @JohannesSchaub-litb:这当然是未来的可能性。迄今为止,没有人提出它(我知道)。本地的 const 禁用 RVO(复制省略)和 C++11“自动移动”规则在很大程度上依赖于 RVO 规则。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-12-21
  • 1970-01-01
  • 2021-09-14
  • 2014-05-06
  • 2021-10-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多