Topic: templated member funcs in templated member funcs


Author: google@vandevoorde.com
Date: Thu, 1 Sep 2005 00:45:13 CST
Raw View
kuyper@wizard.net wrote:
[...]
> > There is a known wording defect in this paragraph (Core issue 431).
> > The note in the next paragraph (14.2/5) makes it quite clear that
> > the second use of "postfix-expression" in 14.2/4 was meant to
> > refer to the subconstruct preceding the "." or "->".
>
> That sounds plausible. Except for one serious problem - the note you
> refer to, and the note that is referenced in Core Issue 431, is not
> present in my copy of the standard. There is a note in 14.2p5, but it's
> text is quite different from what is cited in Core Issue 431: "[_Note_:
> the keyword template may not be applied to non-template members of
> class templates.]". This isn't just a simple mis-citation; I searched
> the entire document for text matching the citation in 431, and couldn't
> find it.
>
> Was this text added after the 1998 release of the standard? I don't
> have copy that reflects any of those changes.

Ah yes.  I just checked the diffs between the 1998 version and
the 2003 version (aka. TC1) of the standard and you're right.
These words were added during that time (apparently for the
resolution of core issue 30).

> As far as I can from the web site, there's one person who agrees with
> the defect report, and no one else who's expressed an opinion. The
> status of 431 is listed as "Drafting". What exactly does that mean?

"Drafting" status means that there is a consensus among the active
participants in the Core working group and that someone has been
assigned to propose specific wording changes to implement that
consensus.

The defect report notes appears to only reflect the e-mail discussion
that
took place.  At the time, only John Spicer responded (he is sometimes
called "Mr. Template" -- when he responded, probably nobody felt the
need to add anything).  Note the "Priority 0": That means that the
issue
is considered "obvious" in some way (which is mostly likely why the
notes
don't contain additional discussion beyond the e-mail capture).  I.e.,
at a
face-to-face meeting the Core WG decided that the report was obviously
right and that the resolution was "easy" -- John was then assigned the
task of writing it up.

        Daveed

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: google@vandevoorde.com
Date: Sat, 27 Aug 2005 00:50:10 CST
Raw View
Zara wrote:
> Change the definition of print_2:
>
>  template<typename T> void  A::print_2() { b.template hallo<T>(); }
>
> This ".template" avoids the compiler interpreting the opening '<' as a
> less-than comparator.
>
> I also think this is sorcery, so there is the reference:
>
> C++ Templates (Vandevoorde-Josuttis), chapter 5, "Tricky Basics"
>
> I have been unable to find if in ISO C++ std, but if it is explained in
> that book, it is most probable it is standard

FWIW, the reference in the standard is 14.2 [temp.names]/4.
In this case "b" is has a template dependent type; so it is indeed
required.

        Daveed

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: AlbertoBarbati@libero.it (Alberto Barbati)
Date: Sat, 27 Aug 2005 17:59:18 GMT
Raw View
google@vandevoorde.com wrote:
> Zara wrote:
>
>>Change the definition of print_2:
>>
>> template<typename T> void  A::print_2() { b.template hallo<T>(); }
>>
>>This ".template" avoids the compiler interpreting the opening '<' as a
>>less-than comparator.
>>
>>I also think this is sorcery, so there is the reference:
>>
>>C++ Templates (Vandevoorde-Josuttis), chapter 5, "Tricky Basics"
>>
>>I have been unable to find if in ISO C++ std, but if it is explained in
>>that book, it is most probable it is standard
>
>
> FWIW, the reference in the standard is 14.2 [temp.names]/4.
> In this case "b" is has a template dependent type; so it is indeed
> required.
>

Maybe I am missing something here, but... b doesn't look dependent at
all to me, as both A and B are a non-template classes. In fact all of
Comeau Online, VC7.1 and gcc 3.3.3 agree to compile the OP's code
without the ".template" syntax. Could it be just a gcc 3.3.1 bug?

Alberto

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: "Zara" <yozara@terra.es>
Date: 29 Aug 2005 07:50:02 GMT
Raw View
> Zara wrote
>> (...)
>> template<typename T> void  A::print_2() { b.template hallo<T>(); }
>> (...)

Alberto Barbati wrote
> (...)
> Maybe I am missing something here, but... b doesn't look dependent at
> all to me, as both A and B are a non-template classes.
> (...)

It is not b which is dependant, it is hallo the dependant one, as the
instantiation refers to <T>, which is a template parameter.

[Reposted with context references, as suggested by group moderator.
Thank's for the point]

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: rtw@freenet.co.uk (Rob Williscroft)
Date: Mon, 29 Aug 2005 15:54:46 GMT
Raw View
Zara wrote in news:1125297398.499345.184950@g44g2000cwa.googlegroups.com
in comp.std.c++:

>> Zara wrote
>>> (...)
>>> template<typename T> void  A::print_2() { b.template hallo<T>(); }
>>> (...)
>
> Alberto Barbati wrote
>> (...)
>> Maybe I am missing something here, but... b doesn't look dependent at
>> all to me, as both A and B are a non-template classes.
>> (...)
>
> It is not b which is dependant, it is hallo the dependant one, as the
> instantiation refers to <T>, which is a template parameter.

hallo isn't a "dependent name", to find hallo and to know that it
is a member template only requires knowledge of b which isn't a
dependant name.

Note what matters is wether the *name* is dependant, instantiations are
always dependant on there paramiters, so there is nothing unusual here.

Rob.
--
http://www.victim-prime.dsl.pipex.com/

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: google@vandevoorde.com
Date: Mon, 29 Aug 2005 10:58:56 CST
Raw View
Alberto Barbati wrote:
> google@vandevoorde.com wrote:
[...]
> > FWIW, the reference in the standard is 14.2 [temp.names]/4.
> > In this case "b" is has a template dependent type; so it is indeed
> > required.
> >
>
> Maybe I am missing something here, but... b doesn't look dependent at
> all to me, as both A and B are a non-template classes. In fact all of
> Comeau Online, VC7.1 and gcc 3.3.3 agree to compile the OP's code
> without the ".template" syntax. Could it be just a gcc 3.3.1 bug?

You're right of course.  I should have actually read the whole
example :-P

g++ 3.4 accepts the code "as is" (well, with some additions to
resolve the iostream uses).

        Daveed

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: kuyper@wizard.net
Date: 29 Aug 2005 16:00:28 GMT
Raw View
Alberto Barbati wrote:
> google@vandevoorde.com wrote:
> > Zara wrote:
> >
> >>Change the definition of print_2:
> >>
> >> template<typename T> void  A::print_2() { b.template hallo<T>(); }
> >>
> >>This ".template" avoids the compiler interpreting the opening '<' as a
> >>less-than comparator.
.
> > FWIW, the reference in the standard is 14.2 [temp.names]/4.
> > In this case "b" is has a template dependent type; so it is indeed
> > required.
>
> Maybe I am missing something here, but... b doesn't look dependent at
> all to me, as both A and B are a non-template classes. In fact all of
> Comeau Online, VC7.1 and gcc 3.3.3 agree to compile the OP's code
> without the ".template" syntax. Could it be just a gcc 3.3.1 bug?

google@vandevoorde.com came to the right conclusion, but specified the
wrong reason. It's not "b" which is dependent, it's "b.hallo<T>".

The relevant clause (14.2p4) says:

"When the name of a member template specialization appears after . or
-> in a _postfix-expression_, or after _nested-name-specifier_ in a
_qualified-id_, and the _postfix-expression_ or _qualified-id_
explicitly depends on a template-parameter (14.6.2), the member
template name must be prefixed by the keyword template."

Note that it's the entire postfix-expression that must be checked for
dependence, not just the the part prior to the '.'. The
postfix-expression in this case is "b.hallo<T>", and it is quite
explicitly dependent on the template parameter T, even though "b"
itself is not dependent on any template parameter.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: kuyper@wizard.net
Date: Mon, 29 Aug 2005 21:41:08 CST
Raw View
Rob Williscroft wrote:
> Zara wrote in news:1125297398.499345.184950@g44g2000cwa.googlegroups.com
> in comp.std.c++:
.
> > It is not b which is dependant, it is hallo the dependant one, as the
> > instantiation refers to <T>, which is a template parameter.
>
> hallo isn't a "dependent name", to find hallo and to know that it
> is a member template only requires knowledge of b which isn't a
> dependant name.
>
> Note what matters is wether the *name* is dependant, instantiations are
> always dependant on there paramiters, so there is nothing unusual here.

The relevant clause says nothing about the name being dependent. The
only thing it says about the name of the template member specialization
is that it occurs after the '.' or '->' in a postfix-expression, or
after the nested-name-specifier in a qualified-id. It's the dependency
of the postfix-expression or the qualified-id containing the name that
renders the 'template' keyword mandatory. As long as the
postfix-expression is dependent, it doesn't matter whether the template
member's name is dependent.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: google@vandevoorde.com
Date: Tue, 30 Aug 2005 09:12:12 CST
Raw View
kuyper@wizard.net wrote:
[...]
> google@vandevoorde.com came to the right conclusion, but specified the
> wrong reason. It's not "b" which is dependent, it's "b.hallo<T>".

No, I just jumped to conclusions.  The code is essentially fine as is.

> The relevant clause (14.2p4) says:
>
> "When the name of a member template specialization appears after . or
> -> in a _postfix-expression_, or after _nested-name-specifier_ in a
> _qualified-id_, and the _postfix-expression_ or _qualified-id_
> explicitly depends on a template-parameter (14.6.2), the member
> template name must be prefixed by the keyword template."
>
> Note that it's the entire postfix-expression that must be checked for
> dependence, not just the the part prior to the '.'. The
> postfix-expression in this case is "b.hallo<T>", and it is quite
> explicitly dependent on the template parameter T, even though "b"
> itself is not dependent on any template parameter.

There is a known wording defect in this paragraph (Core issue 431).
The note in the next paragraph (14.2/5) makes it quite clear that
the second use of "postfix-expression" in 14.2/4 was meant to
refer to the subconstruct preceding the "." or "->".

        Daveed

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: kuyper@wizard.net
Date: 31 Aug 2005 06:20:15 GMT
Raw View
google@vandevoorde.com wrote:
> kuyper@wizard.net wrote:
.
> > The relevant clause (14.2p4) says:
> >
> > "When the name of a member template specialization appears after . or
> > -> in a _postfix-expression_, or after _nested-name-specifier_ in a
> > _qualified-id_, and the _postfix-expression_ or _qualified-id_
> > explicitly depends on a template-parameter (14.6.2), the member
> > template name must be prefixed by the keyword template."
> >
> > Note that it's the entire postfix-expression that must be checked for
> > dependence, not just the the part prior to the '.'. The
> > postfix-expression in this case is "b.hallo<T>", and it is quite
> > explicitly dependent on the template parameter T, even though "b"
> > itself is not dependent on any template parameter.
>
> There is a known wording defect in this paragraph (Core issue 431).
> The note in the next paragraph (14.2/5) makes it quite clear that
> the second use of "postfix-expression" in 14.2/4 was meant to
> refer to the subconstruct preceding the "." or "->".

That sounds plausible. Except for one serious problem - the note you
refer to, and the note that is referenced in Core Issue 431, is not
present in my copy of the standard. There is a note in 14.2p5, but it's
text is quite different from what is cited in Core Issue 431: "[_Note_:
the keyword template may not be applied to non-template members of
class templates.]". This isn't just a simple mis-citation; I searched
the entire document for text matching the citation in 431, and couldn't
find it.

Was this text added after the 1998 release of the standard? I don't
have copy that reflects any of those changes.

As far as I can from the web site, there's one person who agrees with
the defect report, and no one else who's expressed an opinion. The
status of 431 is listed as "Drafting". What exactly does that mean?

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: "frs" <frank_r_schaefer@gmx.net>
Date: Wed, 24 Aug 2005 21:42:56 CST
Raw View
Does the standard forbid templated member functions to
call themselves templated member functions from its members?
Gcc 3.3.1 does not allow it and gives a syntax error. I.e.
in the example below print_1() works, print_2() does not.

Are there compilers that do it. Thanks for any comments
on that issue.

Best Regards,

Frank.

EXAMPLE: --------------------------------------------------------------

class B {
public:
  template <typename T> void hallo();
};

template<> void B::hallo<int>()   { cout << "<int>" << endl; }
template<> void B::hallo<double>(){ cout << "<double>" << endl; }

template<typename T> void Hallo() { }

template<> void Hallo<int>()    { cout << "<int>" << endl; }
template<> void Hallo<double>() { cout << "<double>" << endl; }


class A {
public:
  template <typename T>  void print_1();
  template <typename T>  void print_2();
  B b;
};


template<typename T> void  A::print_1() { Hallo<T>(); }
template<typename T> void  A::print_2() { b.hallo<T>(); }

---------------------------------------------------------------------------

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: v.Abazarov@comAcast.net (Victor Bazarov)
Date: Thu, 25 Aug 2005 15:42:03 GMT
Raw View
frs wrote:
> Does the standard forbid templated member functions to
> call themselves templated member functions from its members?
> Gcc 3.3.1 does not allow it and gives a syntax error. I.e.
> in the example below print_1() works, print_2() does not.
>
> Are there compilers that do it. Thanks for any comments
> on that issue.
>
> Best Regards,
>
> Frank.
>
> EXAMPLE: --------------------------------------------------------------
>
> class B {
> public:
>   template <typename T> void hallo();
> };
>
> template<> void B::hallo<int>()   { cout << "<int>" << endl; }
> template<> void B::hallo<double>(){ cout << "<double>" << endl; }
>
> template<typename T> void Hallo() { }
>
> template<> void Hallo<int>()    { cout << "<int>" << endl; }
> template<> void Hallo<double>() { cout << "<double>" << endl; }
>
>
> class A {
> public:
>   template <typename T>  void print_1();
>   template <typename T>  void print_2();
>   B b;
> };
>
>
> template<typename T> void  A::print_1() { Hallo<T>(); }
> template<typename T> void  A::print_2() { b.hallo<T>(); }

This needs to be

   template<typename T> void  A::print_2() { b.template hallo<T>(); }

if I read the Standard correctly.

V

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: "Zara" <yozara@terra.es>
Date: 26 Aug 2005 03:30:01 GMT
Raw View
Change the definition of print_2:

 template<typename T> void  A::print_2() { b.template hallo<T>(); }

This ".template" avoids the compiler interpreting the opening '<' as a
less-than comparator.

I also think this is sorcery, so there is the reference:

C++ Templates (Vandevoorde-Josuttis), chapter 5, "Tricky Basics"

I have been unable to find if in ISO C++ std, but if it is explained in
that book, it is most probable it is standard

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]