Topic: template as a qualifier


Author: "Sergey P. Derevyago" <ders.NOS@skeptik.net>
Date: 2000/08/14
Raw View
fzhong@my-deja.com wrote:
> >  class X {
> >  public:
> >          template<size_t> friend X* f_adjust() { return 0; }
> >  };
> >  template<class T> void f(T* p)
> >  {
> >                     f_adjust<100>();  // OK
>
> I'm not for sure it is OK here. as per 14.6.5.2 [temp.inject],
> name f_adjust should no be visible at all.
 There is some subtle difference between

 class X {
  public:
       template<size_t> friend X* f_adjust() { return 0; }
 };

and

 class X {
  public:
       template<size_t> friend X* f_adjust();
 };

:)
--
         With all respect, Sergey.          http://cpp3.virtualave.net/
         mailto : ders at skeptik.net

---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Sergey P. Derevyago" <ders.NOS@skeptik.net>
Date: 2000/08/11
Raw View
"Constantine S. Timoshenkov" wrote:
> 14.2/4:
> "When the name of a member template specialization ... explicitly depen=
ds
> on a template=ADparameter (14.6.2), the member template name
> must be prefixed by the keyword template.
> Otherwise the name is assumed to name a non=ADtemplate."
>=20
> Here:
> int* p5=3DAllocator::template get_new2<int>(m);
>=20
> BTW, bcpp 5.5 accepts Allocator::get_new2<int>(m)
 Yes, bcpp 5.5 behaves strange :)

 The full example is:
-----------------------------------8<-----------------------------------
template <class T> void get_new3();

template <class Allocator>
void f(Allocator& m)
{
 int* p1=3D         m.template get_new1<int>( );
 int* p2=3DAllocator::template get_new2<int>(m);
 int* p3=3D                    get_new3<int>(m);
}

struct Alloc {
       template <class T>
       T* get_new1() { return 0; }

       template <class T>
       static T* get_new2(Alloc&) { return 0; }

       template <class T>
       friend T* get_new3(Alloc&) { return 0; }
};

int main()
{
 Alloc a;
 f(a);
}
-----------------------------------8<-----------------------------------
 Note that get_new3 the Alloc's friend follows f() definition and I have =
to
define get_new3 as a template-name somewhere before, 14.2p3:

After name lookup (basic.lookup) finds that a name is a template-name, if=
 this
name is followed by a <, the < is always taken as the beginning of a
template-argument-list and never as a name followed by the less-than oper=
ator.
When parsing a template-id, the first non-nested >
--
         With all respect, Sergey.          http://cpp3.virtualave.net/
         mailto : ders at skeptik.net

---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Constantine S. Timoshenkov" <constim@SoftHome.net.CUT_THIS>
Date: 2000/08/11
Raw View
Sergey P. Derevyago wrote in message <3993EDA8.6835E697@skeptik.net>...
[snip]
>template <class T> void get_new3();
>
>template <class Allocator>
>void f(Allocator& m)
>{
[snip]
>int* p3=                    get_new3<int>(m);
>}
>struct Alloc {
>       template <class T>
>       friend T* get_new3(Alloc&) { return 0; }
>};
Though it appears to compile, is it conforming to specify different
signature in template declaration and definition?

Regards,
Constantine
= constim-at-SoftHome-dot-net =






---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: wmm@fastdial.net
Date: 2000/08/11
Raw View
In article <8n14gh$11su$1@gavrilo.mtu.ru>,
  "Constantine S. Timoshenkov" <constim@SoftHome.net.CUT_THIS> wrote:
> Sergey P. Derevyago wrote in message
<3993EDA8.6835E697@skeptik.net>...
> [snip]
> >template <class T> void get_new3();
> >
> >template <class Allocator>
> >void f(Allocator& m)
> >{
> [snip]
> >int* p3=                    get_new3<int>(m);
> >}
> >struct Alloc {
> >       template <class T>
> >       friend T* get_new3(Alloc&) { return 0; }
> >};
> Though it appears to compile, is it conforming to specify different
> signature in template declaration and definition?

The two declarations of get_new3 declare two different
function templates.  The only reason for the first one is
so that "get_new3" is known to be a template name at the
point where "get_new3<int>" appears; otherwise the "<"
would be taken to be a less-than operator instead of part
of a template-id and there would be a syntax error.
(See 14.8.1p6 for an example of exactly this kind of
machination -- the "using C::f;" in the example fills the
same role as the first declaration of "get_new3" in this
code.)

--
William M. Miller, wmm@fastdial.net
Vignette Corporation (www.vignette.com)


Sent via Deja.com http://www.deja.com/
Before you buy.

---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Sergey P. Derevyago" <ders.NOS@skeptik.net>
Date: 2000/08/11
Raw View
"Constantine S. Timoshenkov" wrote:
> >template <class T> void get_new3();
> >
> >template <class Allocator>
> >void f(Allocator& m)
> >{
> [snip]
> >int* p3=                    get_new3<int>(m);
> >}
> >struct Alloc {
> >       template <class T>
> >       friend T* get_new3(Alloc&) { return 0; }
> >};
> Though it appears to compile, is it conforming to specify different
> signature in template declaration and definition?

The intent of this declaration

 template <class T> void get_new3();

is to ensure that get_new3 is known as a template-name (and nothing more :).
Otherwise the following code

 template <class Allocator> void f(Allocator& m)
 {
  // ...
  int* p3=get_new3<int>(m);
 }

is ill-formed.
--
         With all respect, Sergey.          http://cpp3.virtualave.net/

---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Constantine S. Timoshenkov" <constim@SoftHome.net.CUT_THIS>
Date: 2000/08/12
Raw View
wmm@fastdial.net wrote in message <8n1c3r$s33$1@nnrp1.deja.com>...
>In article <8n14gh$11su$1@gavrilo.mtu.ru>,
>  "Constantine S. Timoshenkov" <constim@SoftHome.net.CUT_THIS> wrote:
>> Sergey P. Derevyago wrote in message
><3993EDA8.6835E697@skeptik.net>...
>> [snip]
>> >template <class T> void get_new3();
>> >
>> >template <class Allocator>
>> >void f(Allocator& m)
>> >{
>> [snip]
>> >int* p3=                    get_new3<int>(m);
>> >}
>> >struct Alloc {
>> >       template <class T>
>> >       friend T* get_new3(Alloc&) { return 0; }
>> >};
>> Though it appears to compile, is it conforming to specify different
>> signature in template declaration and definition?
>
>The two declarations of get_new3 declare two different
>function templates.  The only reason for the first one is
>so that "get_new3" is known to be a template name at the
>point where "get_new3<int>" appears; otherwise the "<"
>would be taken to be a less-than operator instead of part
>of a template-id and there would be a syntax error.
>(See 14.8.1p6 for an example of exactly this kind of
>machination -- the "using C::f;" in the example fills the
>same role as the first declaration of "get_new3" in this
>code.)
>
>--
>William M. Miller, wmm@fastdial.net
>Vignette Corporation (www.vignette.com)

Ah! Thank you for unveiling this.

I'm inclined to think that we definitely need a book named
"Encyclopedia of Surprises of C++" discussing those tricks
in details ;)

Best regards,
Constantine
= constim-at-SoftHome-dot-net =





---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: fzhong@my-deja.com
Date: 2000/08/13
Raw View
In article <3992F06A.2192BE39@skeptik.net>,
  "Sergey P. Derevyago" <ders.NOS@skeptik.net> wrote:

[snip]

>  class X {
>  public:
>          template<size_t> friend X* f_adjust() { return 0; }
>  };
>  template<class T> void f(T* p)
>  {
>                     f_adjust<100>();  // OK

I'm not for sure it is OK here. as per 14.6.5.2 [temp.inject],
name f_adjust should no be visible at all.


Regards

Frank



>            template f_adjust<100>();  // ill-formed
>          ::template f_adjust<100>();  // ill-formed
>  }
> --
>          With all respect, Sergey.
http://cpp3.virtualave.net/
>          mailto : ders at skeptik.net
>
> ---
> [ 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://reality.sgi.com/austern_mti/std-
c++/faq.html              ]
>
>


Sent via Deja.com http://www.deja.com/
Before you buy.

---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Sergey P. Derevyago" <ders.NOS@skeptik.net>
Date: 2000/08/09
Raw View
"Constantine S. Timoshenkov" wrote:
> IIRC, you can use the same syntax for calling static mf as for non-static
> mf:
> struct A
> {
>   void mf() { ... }
>   static void smf() { ... }
> };
> A a;
> a.mf();
> a.smf(); // Same to A::smf();
>
> In your case:
> m.template get_new2<int>(m);
 Well, you are right. However:

 template <class Allocator>
 void f(Allocator& m)
 {
  int* p3=get_new3(m);                // error: qualification required

  int* p4=get_new3<int>(m);           // syntax error -- just like with
                                      // m.get_new<int>()

  int* p5=template get_new3<int>(m);  // syntax error -- we're not allowed
                                      // to do things this way
 }

 struct Alloc3 {
  template <class T>
  friend T* get_new3(Alloc2&) { return 0; }  // now it's a friend
 };

 int main()
 {
  Alloc3 a;
  f(a);
 }

Any ideas? :)
--
         With all respect, Sergey.          http://cpp3.virtualave.net/
         mailto : ders at skeptik.net

---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: James Kuyper <kuyper@wizard.net>
Date: 2000/08/10
Raw View
"Sergey P. Derevyago" wrote:
>
> James Kuyper wrote:
> > >   int* p5=template get_new2<int>(m);  // syntax error -- we're not allowed
> >     int* p5=Allocator::get_new2<int>(m);
>         Are you sure?

No. I'm wrong. That will teach me to rely on memory with a feature that
I've seldom actually used :-) This question is exactly covered by
section 14.3.2p4, and the correct syntax is:

 int* p5 = Allocator::template get_new2<int>(m);

Here's the full text of the example given in 14.3.2p4, for comparison:

class X {
public:
 template<size_t> X* alloc();
 template<size_t> static X* adjust();
};
template<class T> void f(T* p)
{
 T* p1 = p->alloc<200>();
  // ill-formed: < means less than

 T* p2 = p->template alloc<200>();
  // OK: < starts template argument list

 T::adjust<100>();
  // ill-formed: < means less than

 T::template adjust<100>();
  // OK: < starts explicit qualification
}

---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Constantine S. Timoshenkov" <constim@SoftHome.net.CUT_THIS>
Date: 2000/08/10
Raw View
Sergey P. Derevyago wrote in message <399048B7.F2EEFB45@skeptik.net>...
>James Kuyper wrote:
>> >   int* p5=3Dtemplate get_new2<int>(m);  // syntax error -- we're not
>> >   allowed
>>   int* p5=3DAllocator::get_new2<int>(m);
> Are you sure?
14.2/4:
"When the name of a member template specialization ... explicitly depends
on a template=ADparameter (14.6.2), the member template name
must be prefixed by the keyword template.
Otherwise the name is assumed to name a non=ADtemplate."

Here:
int* p5=3DAllocator::template get_new2<int>(m);

BTW, bcpp 5.5 accepts Allocator::get_new2<int>(m)

Regards,
Constantine
=3D constim-at-SoftHome-dot-net =3D




---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Sergey P. Derevyago" <ders.NOS@skeptik.net>
Date: 2000/08/11
Raw View
James Kuyper wrote:
> > > >   int* p5=template get_new2<int>(m);  // syntax error -- we're not allowed
> > >     int* p5=Allocator::get_new2<int>(m);
> >         Are you sure?
> No. I'm wrong. That will teach me to rely on memory with a feature that
> I've seldom actually used :-) This question is exactly covered by
> section 14.3.2p4, and the correct syntax is:
>
>         int* p5 = Allocator::template get_new2<int>(m);
>
> Here's the full text of the example given in 14.3.2p4, for comparison:
 May be you mean 14.2p4? :)

> class X {
> public:
>         template<size_t> X* alloc();
>         template<size_t> static X* adjust();
> };
> template<class T> void f(T* p)
> {
>         T* p1 = p->alloc<200>();
>                 // ill-formed: < means less than
>
>         T* p2 = p->template alloc<200>();
>                 // OK: < starts template argument list
>
>         T::adjust<100>();
>                 // ill-formed: < means less than
>
>         T::template adjust<100>();
>                 // OK: < starts explicit qualification
> }

 Yes, and:

 class X {
 public:
         template<size_t> friend X* f_adjust() { return 0; }
 };
 template<class T> void f(T* p)
 {
                    f_adjust<100>();  // OK
           template f_adjust<100>();  // ill-formed
         ::template f_adjust<100>();  // ill-formed
 }
--
         With all respect, Sergey.          http://cpp3.virtualave.net/
         mailto : ders at skeptik.net

---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: James Kuyper <kuyper@wizard.net>
Date: 2000/08/08
Raw View
"Sergey P. Derevyago" wrote:
...
> Well, and what if I need a static member template? Consider:
...
>   int* p5=template get_new2<int>(m);  // syntax error -- we're not allowed
>                                       // to do things this way

    int* p5=Allocator::get_new2<int>(m);

---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Constantine S. Timoshenkov" <constim@SoftHome.net.CUT_THIS>
Date: 2000/08/08
Raw View
ders.NOS@news.compsol.net wrote in message
<398D54F5.78C7A3A4@skeptik.net>...
>Let's talk about the explicit template qualifier. Sometimes we really need
it:
[First example snipped]
>Well, and what if I need a static member template? Consider:
>
> template <class Allocator>
> void f(Allocator& m)
> {
>  int* p3=get_new2(m);                // error: qualification required
>
>  int* p4=get_new2<int>(m);           // syntax error -- just like with
>                                      // m.get_new<int>()
>
>  int* p5=template get_new2<int>(m);  // syntax error -- we're not allowed
>                                      // to do things this way
> }
>
> struct Alloc2 {
>  template <class T>
>  static T* get_new2(Alloc2&) { return 0; }
> };
>
> int main()
> {
>  Alloc2 a;
>  f(a);
> }
>
>Any ideas?
IIRC, you can use the same syntax for calling static mf as for non-static
mf:
struct A
{
  void mf() { ... }
  static void smf() { ... }
};
A a;
a.mf();
a.smf(); // Same to A::smf();

In your case:
m.template get_new2<int>(m);

HTH,
Constantine
= constim-at-SoftHome-dot-net =




---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Sergey P. Derevyago" <ders.NOS@skeptik.net>
Date: 2000/08/09
Raw View
James Kuyper wrote:
> >   int* p5=template get_new2<int>(m);  // syntax error -- we're not allowed
>     int* p5=Allocator::get_new2<int>(m);
 Are you sure?
--
         With all respect, Sergey.          http://cpp3.virtualave.net/
         mailto : ders at skeptik.net

---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: ders.NOS@news.compsol.net
Date: 2000/08/07
Raw View
Let's talk about the explicit template qualifier. Sometimes we really need it:

 template <class Allocator>
 void f(Allocator& m)
 {
  int* p1=m.get_new<int>();           // syntax error
  int* p2=m.template get_new<int>();  // OK
 }

 struct Alloc1 {
  template <class T>
  T* get_new() { return 0; }
 };

 int main()
 {
  Alloc1 a;
  f(a);
 }

Well, and what if I need a static member template? Consider:

 template <class Allocator>
 void f(Allocator& m)
 {
  int* p3=get_new2(m);                // error: qualification required

  int* p4=get_new2<int>(m);           // syntax error -- just like with
                                      // m.get_new<int>()

  int* p5=template get_new2<int>(m);  // syntax error -- we're not allowed
                                      // to do things this way
 }

 struct Alloc2 {
  template <class T>
  static T* get_new2(Alloc2&) { return 0; }
 };

 int main()
 {
  Alloc2 a;
  f(a);
 }

Any ideas?
--
         With all respect, Sergey.          http://cpp3.virtualave.net/
         mailto : ders at skeptik.net

---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Sergey P. Derevyago" <ders.NOS@skeptik.net>
Date: 2000/08/07
Raw View
Let's talk about the explicit template qualifier. Sometimes we really need it:

 template <class Allocator>
 void f(Allocator& m)
 {
  int* p1=m.get_new<int>();           // syntax error
  int* p2=m.template get_new<int>();  // OK
 }

 struct Alloc1 {
  template <class T>
  T* get_new() { return 0; }
 };

 int main()
 {
  Alloc1 a;
  f(a);
 }

Well, and what if I need a static member template? Consider:

 template <class Allocator>
 void f(Allocator& m)
 {
  int* p3=get_new2(m);                // error: qualification required

  int* p4=get_new2<int>(m);           // syntax error -- just like with
                                      // m.get_new<int>()

  int* p5=template get_new2<int>(m);  // syntax error -- we're not allowed
                                      // to do things this way
 }

 struct Alloc2 {
  template <class T>
  static T* get_new2(Alloc2&) { return 0; }
 };

 int main()
 {
  Alloc2 a;
  f(a);
 }

Any ideas?
--
         With all respect, Sergey.          http://cpp3.virtualave.net/
         mailto : ders at skeptik.net

---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]