If we need both "const?" and "&&?" in a
declaration/definition of a class method or a normal function, I
think it's not difficult for compiler to handle them.
The question isn't so much if it's difficult for the compiler to handle. The difficulty for the compiler probably lies in the fact that the ? can appear arbitrarily late in a declaration. The question is more: what are the specific rules you're proposing and how do they work?
do we really need to write "return
std::move(value)" instead of simply "return value"? the new
compiler should be able to handle it automatically for method with
return type T&&.
Yes. The language will only implicitly move from things that are imminently being destroyed: either local variables or function parameters that have automatic storage duration, or (in C++20) also a few cases where the variable being returned has rvalue reference type. None of these apply here - if you want to move from a member variable, you have to do so explicitly.
also, for your example, do we really need following 2 member
methods returning value of type "T&&" and "const
T&&"?
auto operator*()
&& -> T&& { return
std::move(value); }
auto operator*() const&& -> T const&& {
return std::move(value); }
do you have code example to show the possible usage of these 2
methods?
The first one is clear - if we have an rvalue optional we want to be able to move from its internals instead of copying. The second one, less so. const rvalues are a bit strange, and you can't really move from a const rvalue anyway so there isn't performance gain there if we omit that overload -- but the goal here is to preserve the value category of the input. We get an rvalue in --> we get an rvalue out. The preservation ensures, for instance, that this fails:
auto foo() -> optional<int> const;
std::ref(foo().value()); // foo() is a const rvalue, foo().value() is a int const&&
// and this overload is deleted for rvalues
If we didn't provide the const rvalue overload, foo().value() would have type int const& and we could pass it to std::ref.
Barry