【问题标题】:Why does the const rvalue qualified std::optional::value() return a const rvalue reference?为什么 const rvalue 限定 std::optional::value() 返回 const rvalue 引用?
【发布时间】:2017-10-31 15:05:59
【问题描述】:

std::optional::value() 有以下两个重载

constexpr T& value() &;
constexpr const T & value() const &; 
constexpr T&& value() &&;
constexpr const T&& value() const &&;

返回 const 右值引用有什么意义?

我能想到的唯一原因是让编译器能够在以下(真的很奇怪)情况下帮助捕捉未定义的行为

auto r = std::cref(const_cast<const std::optional<int>&&>(
    std::optional<int>{}).value());

如果std::optional::value() 返回了const T&amp;,那么上面的代码将编译并在稍后使用r reference_wrapper 时导致未定义的行为。

上述返回const T&amp;&amp; 是否有任何其他极端情况?

【问题讨论】:

  • 不能相信其他人的知识,但这里有一个链接:nirfriedman.com/2016/01/18/… 在“可选的安全迭代”部分中,有一些关于在何处使用 T&amp;&amp; value() 的有用信息。跨度>
  • 返回对 const 对象的非常量引用是不安全的……返回对可能是临时对象的左值引用也是不安全的……所以,它返回一个 const右值引用
  • 您建议的替代方案是什么?非const 右值引用? const 左值引用?
  • 我想知道为什么他们需要添加这个重载而不是只添加一个const T&amp; 重载。如果他们需要,为什么不直接返回const T&amp;?这种重载有一些实际用例吗?
  • this 可能重复?归根结底,这个问题只是:T const&amp;&amp; 的意义何在。

标签: c++ c++17 rvalue-reference stdoptional


【解决方案1】:

当然。你在结构中有一个const optional&lt;T&gt;。您返回一个右值实例并访问可选成员。

由于您构建它的方式,您可以保证在这种情况下使用可选。所以你打电话给value()T 类型包含 mutable 状态,可以有效地重用/窃取。 T const&amp;&amp; 重载赋予消费函数窃取该状态的权限。

struct mutable_type {
  mutable std::vector<char> cache;
};
struct test_type {
  const std::optional<mutable_type> bob;
};
test_type factory( int x ) {
  if (x==0) return {};
  return {mutable_type({{1,2,x}})};
}

auto moved_into = factory(3).bob.value().cache;

我相信,这会将vector 移动到bob 中,在这种情况下这是一个const 右值。它依赖于value()const&amp;&amp; 上下文中返回const&amp;&amp;

【讨论】:

  • const T&amp;&amp; 重载如何授予函数窃取其状态的权限?我不认为我遵循...
  • @curious 在这种情况下状态是可变的,因此 const 不会阻止任何内容。 &amp;&amp; 表示该对象是一个右值或被强制转换为一个右值,因此调用者保证不会介意您窃取某些状态。
  • 你能举例说明你的意思吗?
  • @Curious 玩具示例已添加。
  • 即使value() 方法返回了const&amp;,这个例子也不能工作吗?
猜你喜欢
  • 1970-01-01
  • 2020-07-20
  • 1970-01-01
  • 2021-09-17
  • 2011-09-12
  • 1970-01-01
  • 2018-02-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多