lmi
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [lmi] [lmi-commits] master 8ee9eaf 1/7: Don't name unused template p


From: Vadim Zeitlin
Subject: Re: [lmi] [lmi-commits] master 8ee9eaf 1/7: Don't name unused template parameters
Date: Tue, 19 Jan 2021 18:51:02 +0100

On Tue, 19 Jan 2021 15:57:29 +0000 Greg Chicares <gchicares@sbcglobal.net> 
wrote:

GC> On 1/16/21 11:53 AM, Vadim Zeitlin wrote:
GC> > On Sat, 16 Jan 2021 04:07:18 -0500 (EST) Greg Chicares 
<gchicares@sbcglobal.net> wrote:
GC> > 
GC> > GC> branch: master
GC> > GC> commit 8ee9eaf524604021b60b15018ac698529b816d1f
GC> > GC> Author: Gregory W. Chicares <gchicares@sbcglobal.net>
GC> > GC> Commit: Gregory W. Chicares <gchicares@sbcglobal.net>
GC> > GC> 
GC> > GC>     Don't name unused template parameters
GC> > GC>     
GC> > GC>     Making up names for unused template parameters serves no purpose, 
and
GC> > GC>     creates a potential for conflict--for example:
GC> > GC>     
GC> > GC>       template<typename T> class foo
GC> > GC>       {
GC> > GC>         template<typename T> friend void bar();
GC> > GC>                           ^ shadows 'T'
GC> > GC>         template<typename U> friend void baz();
GC> > GC>                           ^ shadows 'U' if added later
GC> > GC>         template<typename> friend void bar();
GC> > GC>                          ^ can never shadow anything
GC> > 
GC> >  While I agree that not using useless names like "T" or "U" is better than
GC> > using them, I think the best solution could be to use meaningful names for
GC> > the template parameters instead.
GC> 
GC> In some cases, I agree. OTOH, here:
GC> 
GC>  template<typename ClassType, typename ValueType>
GC>  class holder final
GC>      :public placeholder
GC>  {
GC>      // Friendship is extended to class any_member only to support its
GC>      // cast operations.
GC> -    template<typename T> friend class any_member;
GC> +    template<typename> friend class any_member;
GC> 
GC> I'm not sure there can be a more meaningful name than 'T'
GC> (or the empty name, which I prefer). The intention is to befriend this:
GC>     template<typename ClassType> friend class any_member; // error

 I was not totally sure about this, thanks for confirming it. However in
this case I believe this friend declaration isn't the right thing to do at
all, at least pedantically speaking, and we should use

        friend class any_member<ClassType>;

instead (after forward declaring any_member template previously, if
necessary).

GC> And if I were to criticize
GC>   template<typename F> class AliquotTimer
GC> I might suggest
GC>   template<typename NullaryFunction> class AliquotTimer
GC> instead. OTOH, a deliberately obscure single-letter template
GC> parameter encourages maintainers to read the commentary:
GC> 
GC>   /// Template parameter 'F' is the type of the first ctor parameter,
GC>   /// which either is a nullary function or behaves like one.
GC> 
GC> so I think that's fine as is.

 It's fine because "F" is a common abbreviation for "function" and if it
were really important to emphasize that is is nullary, I'd use function
pointer and not function/functor type as template parameter. But I think
"VoidNullaryFunction" wouldn't be a bad name either.

GC> But if I were to change that
GC> parameter to "NullaryFunction", it would just be a nuisance
GC> to have to change it in the friend declaration too, yet
GC> leaving the old parameter in the friend declaration would
GC> introduce a gratuitous difference--whereas, with this change:
GC> 
GC>  class LMI_SO Timer
GC>  {
GC>      friend class TimerTest;
GC> -    template<typename F> friend class AliquotTimer;
GC> +    template<typename> friend class AliquotTimer;
GC> 
GC> that concern does not arise.

 I'm not sure we absolutely need to be consistent with the names in the
template definitions and declarations. Here the intention seems to be
equally clear both with just "F" and without any name at all: we want to
make any AliquotTimer a friend of this class and it's hard to argue that
"F" adds much, but OTOH it doesn't bother me to have it neither, and this
even if it's called "VoidNullaryFunction" in the definition of the
template.

 I.e. the difference here seems to be slight while the difference in the
cases when the name does matter is more important. But it's still not very
important, of course.

 And the most important, while still being far from being critical, thing
is to use narrower friend declarations when we really want to be friends
with the instantiation of the other template for the same type only, and
not with all its instantiations no matter the type.

 Regards,
VZ

Attachment: pgpMzZuZ8yphq.pgp
Description: PGP signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]