Date: Sun, 15 Dec 2019 22:52:02 -0700
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
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-15 23:54:19