incubator-stdcxx-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Martin Sebor <se...@roguewave.com>
Subject Re: [VOTE] naming convention for variadic template arguments
Date Sat, 28 Jun 2008 18:16:44 GMT
Travis Vitek wrote:
> 
> 
>> Eric Lemings wrote:
>>> Martin Sebor 
>>>
>>> This thread kind of fizzled out so let me resurrect it and reiterate
>>> the proposed naming convention to follow unless more specific names
>>> are appropriate:
>>>
>>>      template <class _TypeT, class... _Types>     # 1
>>>
>>> This is in contrast to other styles, including:
>>>
>>>      template <class _Type, class... _Types>      # 2
>>>      template <class _HeadT, class... _TailT>     # 3
>>>      template <class _TType, class... _UTypes>    # 4
>>>
>>> The rationale for the proposed convention (#1) is that:
>>>
>>>    A) unlike the alternatives, the first name (_TypeT) follows
>>>       a well-established and entrenched convention for template
>>>       parameters used throughout the library
>>>    B) also unlike the alternatives, it is being used in the
>>>       implementation of <type_traits>
>>>    C) unlike (#2) (although not as well as #3) it more clearly
>>>       distinguishes between the name of the first parameter and
>>>       the parameter pack
>>>
> 
> [...]
> 
>> In this case, it depends on whether the two parameters are actually part
>> of the same type list.  If _TypesT and _Types are actually part of the
>> same type list then they should be named either _TypeT and _TypesT
>> respectively (or _Type and _Types as shown in #2).  If they are not part
>> of the same type list, then they should be named _TypeT and _TypesU
>> (similar to #4).

This makes sense. The only potential problem is that (I suspect)
it may not necessarily be known at the point of the declaration
of every template whether the types are related or not (just like
an InputIterator in some container member function templates may
not be an iterator at all but size_type). But that case can be
handled by simply assuming that the types are related (analogous
to the InputIterator case).

>>
>> In any case, a plural name should implicitly denote a template parameter
>> pack (which actually should rule out #3 even though I've already been
>> using it).  :P

Agreed.

>>
>> Brad.
> 
> I'm with Brad

Yet each of you is using different names both in your code and
in your responses to this thread...

> 
>> Check the box below to vote:
>>
>>    [ ] In favor
>>    [x] Opposed (suggest an improvement and rationale)
>>
> 
> I think the names really depend on the intent and where it is being used. If you have
a parameter pack that is essentially a single typelist, like so...
> 
>   template <class... _TTypes> struct S;
> 
> I'd expect the first template parameter and the parameter pack to have similar names.
The above will likely break down to the following recursive template declaration...
> 
>   template <class _TypeT> struct S;
>   template <class _TypeT, class... _TTypes> struct S;

Did you mean _TTypes or _TypesT?

There's not a single occurrence of _TTypes in any of your or Brad's
code. You use _Types and Brad _Types, _TypesT, _TailT, or _TailT1
(with the trailing T and 1 possible being U or 2, as needed).

I will assume you meant _TypesT and _TypesU because that's what
you've been using in your code. It also seems more in keeping
with the naming convention for ordinary (non-variadic) template
parameters. Plus I like how the T or U at end stands out. Other
than that, I don't really care all that much if we end up with
_TTypes or _TypesT. What I do care about is consistency.

> 
> If, on the other hand, the first argument stands alone and the parameter pack is a typelist,
then I'd expect something more like the following...
> 
>   template <class _TypeT, class... _UTypes>  struct S;
> 
>   template <class _TypeT, class _TypeU> struct S;
>   template <class _TypeT, class _TypeU, class... _UTypes> struct S;

I realize the convention I proposed has at least one other
shortcoming in that it doesn't scale to member templates:

     template <class _TypeT, class... _Types>
     struct Parent {
         template <class _TypeU, class... _Types???>
         Child {
             template <class _TypeV, class... _Types???>
             Grandchild { };
         };
     };

To account for this, taking into account the existing convention
(and assuming your _TTypes was really meant to be _TypesT), the
generic case would look like so:

     template <class... _TypesT>
     struct Parent {
         template <class... _TypesU>
         Child {
             template <class... _TypesV>
             Grandchild { };
         };
     };

Applying Brad's proposal (if I understand it correctly) to related
types, we'd have this:

     template <class _TypeT, class... _TypesT>
     struct Parent {
         template <class _TypeU, class... _TypesU>
         Child {
             template <class _TypeV, class... _TypesV>
             Grandchild { };
         };
     };

and for unrelated types this:

     template <class _TypeT, class... _TypesU>
     struct Parent {
         template <class _TypeV, class... _TypesW>
         Child {
             template <class _TypeX, class... _TypesY>
             Grandchild { };
         };
     };

Does this look okay to everyone?

Martin

Mime
View raw message