Why does the const rvalue value match std :: optional :: value () returns a const rvalue reference?

std::optional::value() has the following two overloads

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

What is the point of returning a const rvalue link?

The only reason I can think of is to turn on the compiler to help catch undefined behavior in (really really weird) cases like

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

Where, if std::optional::value() returned const T& , then the above code will compile and lead to undefined behavior when r reference_wrapper is used.

Is there any other angular case where the above returns a const T&& ?

+5
source share
1 answer

Sure. You have const optional<T> in the structure. You return an instance of rvalue and gain access to an optional member.

Because of how you built it, you can guarantee that in this case an additional one is involved. Therefore, you call value() . Type T contains a mutable state that can be effectively reused / stolen. Overloading T const&& gives permission to the consumption function to steal this state.

 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; 

This, I believe, moves the vector within the bob , which is const rvalue in this context. It relies on value() , which returns const&& in the context of const&& .

+6
source

Source: https://habr.com/ru/post/1268376/


All Articles