C++ Logo

std-proposals

Advanced search

Re: Generic template 'this'

From: Phil Bouchard <phil_at_[hidden]>
Date: Mon, 9 Mar 2020 10:56:39 -0400
... Also we could limit generic ‘this’ overloads to specific namespaces:

template <typename Class>
    ostream & boost::detail::Class::operator << (ostream & out) { ... }

-- 
Phil Bouchard
Founder
C.: (819) 328-4743
> On Mar 8, 2020, at 7:36 PM, Phil Bouchard <phil_at_[hidden]> wrote:
> 
> ... And only the classes with the proper declarations would take advantage of the generic template 'this':
> 
> 
> 
> -- 
> 
> Phil Bouchard
> Founder
> C.: (819) 328-4743
> 
> 
> 
> 
> 
>> On 3/8/20 7:34 PM, Phil Bouchard wrote:
>> What I have in mind is to clean up the dispatch fiasco that is done with either the constructors or the cast operator right now. Conversions, comparisons, ... should be simplified as well. For example:
>> 
>> struct X
>> 
>> {
>> 
>>     int value;
>> 
>> 
>> 
>>     template <typename T>
>> 
>>         X(T const & T);
>> 
>>     template <typename T>
>> 
>>         operator T ();
>> 
>> };
>> 
>> struct Y
>> 
>> {
>> 
>>     int value;
>> 
>> 
>> 
>>     template <typename T>
>> 
>>         Y(T const & T);
>> 
>>     template <typename T>
>> 
>>         operator T ();
>> 
>> };
>> 
>> template <typename Class, typename T>
>> 
>>     inline Class::operator T () { return T(* this); } // generic constructor wrapper
>> 
>> template <typename Class, typename T>
>> 
>>     inline Class::Class(T const &t) { value = t.value; } // cast operation really done here
>> 
>> 
>> 
>> And normal specializations here:
>> 
>> template <typename T>
>> 
>>     inline X::X(T const &t) { value = t.value; } // specialized cast operation done here
>> 
>> 
>> 
>> Also if we had a way to iterate all members (which would be another important proposal) then we could also have a generic "operator <<" as well:
>> 
>> template <typename Class>
>> 
>>     ostream & Class::operator << (ostream & out)
>> 
>>     {
>> 
>>         for (member_iterator<Class> i = member_iterator<Class>::begin(); i != member_iterator<Class>::end(); ++ i)
>> 
>>         {
>> 
>>             if (i != member_iterator<Class>::begin())
>> 
>>                 out << ", ";
>> 
>>             out << this->*i;
>> 
>>         }
>> 
>>         return out;
>> 
>>     }
>> 
>> The aforementioned should also remove the need for these global friend function overloads.
>> 
>> 
>> 
>> -- 
>> 
>> Phil Bouchard
>> Founder
>> C.: (819) 328-4743
>> 
>> 
>> 
>> 
>> 
>>> On 3/8/20 6:03 PM, Jake Arkinstall wrote:
>>> For me, this approach has some merits, but this particular example is something that, to me, makes much more sense as a free function.
>>> 
>>> Do you have further examples? 
>>> 
>>>> On Sun, 8 Mar 2020, 21:55 Phil Bouchard via Std-Proposals, <std-proposals_at_[hidden]> wrote:
>>>> Well I believe a proposal should be open for debate, just like a thesis.
>>>> 
>>>> We both agree these overloads should be simplified but we disagree on the syntax.
>>>> 
>>>> I saw the recursive lambda thing and I think I already talked to you before regarding CV overloads but we were proposing the following syntax:
>>>> 
>>>> struct A
>>>> 
>>>> {
>>>> 
>>>>     template <bool BC>
>>>> 
>>>>         void foo() bool<BC>
>>>> 
>>>>         {
>>>> 
>>>>         }
>>>> 
>>>> };
>>>> 
>>>> And regarding the this generic overloading I still believe the following syntax is cleaner:
>>>> 
>>>> struct A
>>>> 
>>>> {
>>>> 
>>>>     template <typename T>
>>>> 
>>>>         bool compare(T const &);
>>>> 
>>>> }; 
>>>> 
>>>> template <typename C, typename T>
>>>> 
>>>>     void C::compare(C const &)
>>>> 
>>>>     {
>>>> 
>>>>         ...
>>>> 
>>>>     }
>>>> 
>>>> Because with your syntax I could technically reassign "self":
>>>> 
>>>> struct A
>>>> 
>>>> {
>>>> 
>>>>     template <typename C, typename T>
>>>> 
>>>>         bool compare(this C & c, T const &);
>>>> 
>>>> }; 
>>>> 
>>>> template <typename C, typename T>
>>>> 
>>>>     bool C::compare(this C & c, T const &) // redundant C here
>>>> 
>>>>     {
>>>> 
>>>>         static C sc = C();
>>>> 
>>>>         c = sc; // in theory we could do this unless you patch the compilers with a new error for that specific case
>>>> 
>>>>     }
>>>> 
>>>> 
>>>> 
>>>> -- 
>>>> 
>>>> Phil Bouchard
>>>> Founder
>>>> C.: (819) 328-4743
>>>> 
>>>> 
>>>> 
>>>> 
>>>> 
>>>>> On 3/8/20 5:37 AM, Gašper Ažman wrote:
>>>>> I meant that you should consider the incremental value of your proposal over p0847, which is on track for c++23 unless serious issues crop up
>>>>> 
>>>>>> On Sat, Mar 7, 2020, 19:04 Phil Bouchard <phil_at_[hidden]> wrote:
>>>>>> The syntaxes are way different:
>>>>>> 
>>>>>> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p0847r4.html
>>>>>> 
>>>>>> In your case the compiler will have to change all of its rules for the number of parameters "operator" overloads. For example:
>>>>>> 
>>>>>> struct A
>>>>>> 
>>>>>> {
>>>>>> 
>>>>>>     int value;
>>>>>> 
>>>>>>     ...
>>>>>> 
>>>>>>     template <typename Self>
>>>>>> 
>>>>>>         bool operator < (this Self && self, A const & a) // 2 parameters... ok
>>>>>> 
>>>>>>         {
>>>>>> 
>>>>>>             return self.value < a.value;
>>>>>> 
>>>>>>         }
>>>>>> 
>>>>>> 
>>>>>> 
>>>>>>         bool operator < (A const & a) // 1 parameter... ok
>>>>>> 
>>>>>>         {
>>>>>> 
>>>>>>             return value < a.value;
>>>>>> 
>>>>>>         }
>>>>>> 
>>>>>> };
>>>>>> 
>>>>>> 
>>>>>> 
>>>>>> -- 
>>>>>> 
>>>>>> Phil Bouchard
>>>>>> Founder
>>>>>> C.: (819) 328-4743
>>>>>> 
>>>>>> 
>>>>>> 
>>>>>> 
>>>>>> 
>>>>>>> On 3/7/20 1:35 PM, Gašper Ažman wrote:
>>>>>>> P0847
>>>>>>> 
>>>>>>>> On Sat, Mar 7, 2020, 18:33 Phil Bouchard via Std-Proposals <std-proposals_at_[hidden]> wrote:
>>>>>>>> Alright, I'm pretty sure this is not implemented yet. Suppose you have:
>>>>>>>> 
>>>>>>>> struct A
>>>>>>>> 
>>>>>>>> {
>>>>>>>> 
>>>>>>>>     int value;
>>>>>>>> 
>>>>>>>>     ...
>>>>>>>> 
>>>>>>>>     template <typename T>
>>>>>>>> 
>>>>>>>>         int compare(T const & t) const;
>>>>>>>> 
>>>>>>>> }
>>>>>>>> 
>>>>>>>> 
>>>>>>>> 
>>>>>>>> struct B
>>>>>>>> 
>>>>>>>> {
>>>>>>>> 
>>>>>>>>     int value;
>>>>>>>> 
>>>>>>>>     ...
>>>>>>>> 
>>>>>>>>     template <typename T>
>>>>>>>> 
>>>>>>>>         int compare(T const & t) const;
>>>>>>>> 
>>>>>>>> }
>>>>>>>> 
>>>>>>>> 
>>>>>>>> 
>>>>>>>> Then a generic way to define the same functionality for all classes would be to have a "template 'this'":
>>>>>>>> 
>>>>>>>> template <typename C, typename T>
>>>>>>>> 
>>>>>>>>         inline int C::compare(T const & t) const
>>>>>>>> 
>>>>>>>>         {
>>>>>>>> 
>>>>>>>>             return value == t.value ? 0 : value < t.value ? -1 : 1;
>>>>>>>> 
>>>>>>>>         }
>>>>>>>> 
>>>>>>>> 
>>>>>>>> 
>>>>>>>> (Please include my email address in your replies)
>>>>>>>> 
>>>>>>>> 
>>>>>>>> 
>>>>>>>> -- 
>>>>>>>> 
>>>>>>>> Phil Bouchard
>>>>>>>> Founder
>>>>>>>> C.: (819) 328-4743
>>>>>>>> 
>>>>>>>> 
>>>>>>>> -- 
>>>>>>>> Std-Proposals mailing list
>>>>>>>> Std-Proposals_at_[hidden]
>>>>>>>> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>>>> -- 
>>>> Std-Proposals mailing list
>>>> Std-Proposals_at_[hidden]
>>>> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals

Received on 2020-03-09 09:59:27