为什么 const 右值限定 std::optional::value() return 是一个 const 右值引用?
Why does the const rvalue qualified std::optional::value() return a const rvalue reference?
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&
,那么上面的代码将编译并在稍后使用 r
reference_wrapper
时导致未定义的行为。
上面的返回 const T&&
是否还有其他极端情况?
当然可以。您在结构中有一个 const optional<T>
。您 return 一个右值实例并访问可选成员。
由于您构建它的方式,您可以保证在这种情况下使用可选。所以你调用value()
。类型 T
包含 mutable
可以有效地成为 reused/stolen 的状态。 T const&&
重载允许消费函数窃取该状态。
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()
return 在 const&&
上下文中 const&&
。
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&
,那么上面的代码将编译并在稍后使用 r
reference_wrapper
时导致未定义的行为。
上面的返回 const T&&
是否还有其他极端情况?
当然可以。您在结构中有一个 const optional<T>
。您 return 一个右值实例并访问可选成员。
由于您构建它的方式,您可以保证在这种情况下使用可选。所以你调用value()
。类型 T
包含 mutable
可以有效地成为 reused/stolen 的状态。 T const&&
重载允许消费函数窃取该状态。
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()
return 在 const&&
上下文中 const&&
。