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: Sun, 15 Dec 2019 23:58:50 -0700
and one more thing, for your example

template <typename T>
class optional {
     union { char _; T value; };
     bool has_value;
public:
     auto operator*() & -> T& { return value; }
     auto operator*() const& -> T const& { return value; }
     auto operator*() && -> T&& { return std::move(value); }
     auto operator*() const&& -> T const&& { return std::move(value); }
};

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&&.

Best Regards,

Jianping

On 12/15/2019 10:52 PM, jianping z 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.
>
> based on your sample, let's say compiler encounters "const?" first
> (vice versa)
>
> compiler deal with "const?" first to generate two copies of the
> function from origin function
> 1. with const? removed (&&? not handled yet)
> 2. with const? replaced with const (&&? not handled yet)
>
> then, as "&&?" is in both of these 2 generated functions, compiler can
> now deal with "&&?" to geneate two copies of the function from each of
> these 2 functions
> 1. with &&? replaced with &
> 2. with &&? replaced with &&
>
> finally, 4 functions generated. it is still easy for compiler to
> generate, just take one more step to check the generated code to find
> if further process needed. how do you think?
>
> Best Regards,
>
> Jianping
>
>
> On 12/15/2019 04:41 PM, Barry Revzin wrote:
>> On Fri, Dec 13, 2019 at 12:58 AM jianping z via Std-Proposals
>> <std-proposals_at_[hidden]
>> <mailto:std-proposals_at_[hidden]>> wrote:
>>
>> // example-1b.hpp : much more concise, no more duplicated code (less
>> error prone)
>> class elements
>> {
>> int elem[10];
>> const? int& operator[](size_t n) const? { return elem[n]; }
>> const? int* data() const? { return elem; }
>> const? int* begin() const? { return elem; }
>> const? int* end() const? { return elem+10; }
>> }
>>
>>
>> I think this is pretty nice, and I appreciate the examples clearly
>> illustrating how this is intended to work.
>>
>> const or not const isn't the only axis we have to deal with though -
>> we have one more: lvalue or rvalue. Today, optional::operator*()
>> looks something like this (reduced for sanity):
>>
>> template <typename T>
>> class optional {
>> union { char _; T value; };
>> bool has_value;
>> public:
>> auto operator*() & -> T& { return value; }
>> auto operator*() const& -> T const& { return value; }
>> auto operator*() && -> T&& { return std::move(value); }
>> auto operator*() const&& -> T const&& { return std::move(value); }
>> };
>>
>> Now, with the const? feature, I could reduce these four overloads to
>> two:
>>
>> template <typename T>
>> class optional {
>> union { char _; T value; };
>> bool has_value;
>> public:
>> auto operator*() const?& -> T const?& { return value; }
>> auto operator*() const?&& -> T const?&& { return std::move(value); }
>> };
>>
>> It'd really be nice to just have the one overload here. But with
>> &/&&, it doesn't work as nicely since the question is no longer "to
>> token or not to token", but rather a choice of two tokens. Maybe
>> that's... fine and we could just say that &&? means & or && while
>> const? means const or nothing. So that this spits out four functions
>> for us:
>>
>> template <typename T>
>> class optional {
>> union { char _; T value; };
>> bool has_value;
>> public:
>> auto operator*() const?&&? -> T const?&&? { return static_cast<T
>> const?&&?>(value); }
>> };
>>
>> Maybe this is too ugly, maybe we need a different way to pick
>> references. But regardless one problem is that we'd need these two to
>> unpack independently (that is, get the full cartesian product of
>> {const, } x {&, &&}). But this goes against one of your examples
>> where you illustrated:
>>
>> template<typename T>
>> const? T& max(const? T& a, const? T& b)
>>
>> as become two function templates (rather than four).
>>
>> This 4x thing comes up a lot. std::get for std::tuple for instance
>> might become:
>>
>> template <size_t I, typename... Ts>
>> auto get(tuple<Ts...> const?&&?) -> tuple_element_t<I,
>> tuple<Ts...>>const?&&?;
>>
>> Something to think about.
>>
>> Barry

Received on 2019-12-16 01:01:17