Date: Mon, 16 Dec 2019 14:06:47 -0700
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?
Best Regards,
Jianping
On 12/15/2019 11:58 PM, jianping z wrote:
>
> 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
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?
Best Regards,
Jianping
On 12/15/2019 11:58 PM, jianping z wrote:
>
> 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 15:09:16