C++ Logo

std-proposals

Advanced search

Re: proposal: new const-able feature ( use "const?" , or new "constable" keyword) for method/function

From: jianping z <zjpwork_at_[hidden]>
Date: Tue, 17 Dec 2019 14:20:30 -0700
Thank you and Michael Hava for the updates, it turns out my C++
knowledge needs to be updated to C++17.

Here are some of my thoughts about your concern,

1. the "&&?" notation
we may treat "&&" as a token having two "&", and each "?" can optionally
remove one "&",
following the rule, "&&??" can be used to optionally remove two "&" from
"&&" with "??".

a) const? -> (), const //2 variations with single "?"
b) &? -> (), & //2 variations with single "?"
c) &&? -> &, && //2 variations with single "?"
d) &&?? -> (), &, && //3 variations with double "?" ("??")

here, left side is the notations, right side are the variations of the
final tokens to replace the notation, "()" means no token (notation removed)
by explaining "?" like this, developer may able to accept this concept
easily. though "&?", and "&&??" are hardly needed, but they may still be
usefully, for example

//declared with "&?"
int&? max(int&? a, int&? b) { return a > b ? a : b; } //"&?" can appear
more than once in a declaration

//result of "&?"
int max(int a, int b) { return a > b ? a : b; } //all "&?" are removed
int& max(int& a, int& b) { return a > b ? a : b; } //all "&?" are
replaced with "&"

2. the rule
the rule which I would like to suggest for notation "const?", "&?",
"&&?", "&&??" appeared in a declaration/definition of a function/method.
a) each notation may appear multiple times in a declaration.
b) each notation may appear multiple times in a definition (including
its body).
b) for each declaration or definition, usually only one reference type
notation ( "&?", "&&?", "&&??") can appear, otherwise, too many
combinations (if really needed, this restriction can be ignored)
c) for each declaration or definition, when a notation is found, a set
of declaration/definition will be generated according to the variations
of notation
d) for each generated declaration or definition, all appearances of same
notation are replaced with same token.
e) if the generated declaration/definition still contains other
notation, repeat c)

3. the return value
I think the compiler should be updated to treat a reference to member
value of rvalue object as rvalue reference as well, for example

class A
{
   int value;
   int& value() & { return value; } //okay
   int&& Value() && { return value; } //should be okay, no std::move()
should be needed, as this method applies to A&& (rvalue object)
   int&& Value() & { return value; } //wrong, as this method applies to
A& (lvalue object), std::move() should be required here
}

if compiler can to work as expected, we can write method like with new
notation

const? int&&? Value() const? &&? { return value; }

Best Regards,

Jianping

On 12/17/2019 06:07 AM, Barry Revzin wrote:
> On Sun, Dec 15, 2019 at 11:51 PM jianping z <zjpwork_at_[hidden]
> <mailto:zjpwork_at_[hidden]>> wrote:
>
> 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?
>
> On Mon, Dec 16, 2019 at 12:58 AM jianping z <zjpwork_at_[hidden]
> <mailto:zjpwork_at_[hidden]>> wrote:
>
> 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.
>
> On Mon, Dec 16, 2019 at 3:06 PM jianping z <zjpwork_at_[hidden]
> <mailto:zjpwork_at_[hidden]>> wrote:
>
> 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


Received on 2019-12-17 15:22:58