Topic: Can a template class have a nested template class?


Author: gn@langner.com (McNepp)
Date: Thu, 16 Aug 2001 20:11:34 GMT
Raw View
Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr> wrote in message news:<flitfqqsrz.fsf@pizza.cmla.ens-cachan.fr>...
> emarkp@CSUA.Berkeley.EDU (E. Mark Ping) writes:
>
> | That is, is the following code legal?
> |
> | template <class T> class Outer
> | {
> |   template <class U> class Inner
> |   {
> |   };
> | };
>
> Yes, the above is well-formed and common practice.
>
> | And if so, then can the inner class be explicitly specialized?
> | e.g.:
> |
> |
> | template <class T> class Outer
> | {
> |   template <bool flag> class Inner;
> |   template <> class Inner<true> {};
> |   template <> class Inner<false> {};
> | };
>
> No, it is ill-formed: a declaration of an explicit specialization
> cannot appear at class-scope:

Aaaargh! What a shock! This renders all my carefully designed
"partial-specialization-workarounds" illegal!
I guess we all agree that the above code is essential when working
with MS Visual C++ in order to obtain the benefits of partial
specialization. It has worked very well until now...
So, what can I do? Is there any workaround for Standard-abiding
programmers who are stuck with MS VC++ ?
Can I sign a petition somewhere to declare the above code legal?
Can I sign a petiion somewhere to declare VC++ illegal?

---
[ 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.research.att.com/~austern/csc/faq.html                ]





Author: "John Hickin" <hickin@nortelnetworks.com>
Date: Fri, 17 Aug 2001 18:53:46 GMT
Raw View

Gabriel Dos Reis wrote:
>

>
> No, it is ill-formed: a declaration of an explicit specialization
> caanot appear at class-scope:
>
> 14.7.3/2
>   An explicit specialization shall be declared in the namespace of
>   which the template is a member, or, for member templates, in the
>   namespace of which the enclosing class or enclosing class template
>   is member. An explicit specialization of a member function, member
>   class or static data member of a class template shall be declared in
>   the namespace of which the class template is a member. Such a
>   declaration may also be a definition. If the declaration is not a
>   definition, the specialization may be defined later in the
>   name-space in which the explicit specialization was declared, or in
>   a namespace that encloses the one in which the explicit
>   specialization was declared.
>

I interpret this part to mean that if my templated class is in some
namespace N then explicit specializations should appear in the same
namespace N and not somewhere else. A specialization inside a class
would be OK provided that the class itself was in the proper namespace.
I don't interpret this as requiring the declaration to be at the
top-level scope of the namespace.

As support for this view consider the following example inspired by
14.5.4 Class template partial specializations /7:

  namespace N { template<typename T1, typename T2> struct A { }; }
  using N::A;
  namespace N { template<typename T> struct A<T,T*> { int bar() { return
42; } }; }
  N::A<int,int*> foo;
  int xyzzy = foo.bar(); // compiles just fine

If you move the specialization to the global scope it is a compile time
error. Of course my compiler and my view may be incorrect here. I'm OK
with that but I'd really like the specializations referred to in the
original posting to be legal.


Regards, John.

---
[ 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.research.att.com/~austern/csc/faq.html                ]





Author: Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr>
Date: Fri, 17 Aug 2001 16:24:46 CST
Raw View
"John Hickin" <hickin@nortelnetworks.com> writes:

| Gabriel Dos Reis wrote:
| >
|
| >
| > No, it is ill-formed: a declaration of an explicit specialization
| > caanot appear at class-scope:
| >
| > 14.7.3/2
| >   An explicit specialization shall be declared in the namespace of
| >   which the template is a member, or, for member templates, in the
| >   namespace of which the enclosing class or enclosing class template
| >   is member. An explicit specialization of a member function, member
| >   class or static data member of a class template shall be declared in
| >   the namespace of which the class template is a member. Such a
| >   declaration may also be a definition. If the declaration is not a
| >   definition, the specialization may be defined later in the
| >   name-space in which the explicit specialization was declared, or in
| >   a namespace that encloses the one in which the explicit
| >   specialization was declared.
| >
|
| I interpret this part to mean that if my templated class is in some
| namespace N then explicit specializations should appear in the same
| namespace N and not somewhere else. A specialization inside a class
| would be OK provided that the class itself was in the proper namespace.

No, re-read the first and second sentences.

| I don't interpret this as requiring the declaration to be at the
| top-level scope of the namespace.
|
| As support for this view consider the following example inspired by
| 14.5.4 Class template partial specializations /7:
|
|   namespace N { template<typename T1, typename T2> struct A { }; }
|   using N::A;
|   namespace N { template<typename T> struct A<T,T*> { int bar() { return
| 42; } }; }
|   N::A<int,int*> foo;
|   int xyzzy = foo.bar(); // compiles just fine

This is a completely *different* issue.

[...]

| I'd really like the specializations referred to in the
| original posting to be legal.

Ah, what you would like is completely -different- from what the
Standard does actually say :-) -- and some would also like what you
want, but we have to recognize that we can't bend the Standard words
to say whhat they don't actually say.  Maybe an extension in future
revision if it turns out not to be a good technical reason to put that
restriction, now that we have more experience with templates than we
had before standardization completed.

--
Gabriel Dos Reis, dosreis@cmla.ens-cachan.fr

---
[ 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.research.att.com/~austern/csc/faq.html                ]





Author: comeau@panix.com (Greg Comeau)
Date: Sat, 18 Aug 2001 12:49:50 GMT
Raw View
In article <3B7D6845.F72AA8FB@nortelnetworks.com>,
John Hickin <hickin@nortelnetworks.com> wrote:
>Gabriel Dos Reis wrote:
>> 14.7.3/2....
>I interpret this part to mean that if my templated class is in some
>namespace N then explicit specializations should appear in the same
>namespace N and not somewhere else.

Ok.

>A specialization inside a class
>would be OK provided that the class itself was in the proper namespace.
>I don't interpret this as requiring the declaration to be at the
>top-level scope of the namespace.

That seems to sound ok, except for the "inside a class part",
which isn't allowed, if I understand you.
--
Greg Comeau                 Countdown to "export": December 1, 2001
Comeau C/C++ ONLINE ==>     http://www.comeaucomputing.com/tryitout
World Class Compilers:  Breathtaking C++, Amazing C99, Fabulous C90.
Comeau C/C++ with Dinkumware's Libraries... Have you tried it?

---
[ 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.research.att.com/~austern/csc/faq.html                ]





Author: emarkp@CSUA.Berkeley.EDU (E. Mark Ping)
Date: Tue, 14 Aug 2001 19:39:30 GMT
Raw View
That is, is the following code legal?

template <class T> class Outer
{
  template <class U> class Inner
  {
  };
};

And if so, then can the inner class be explicitly specialized?
e.g.:


template <class T> class Outer
{
  template <bool flag> class Inner;
  template <> class Inner<true> {};
  template <> class Inner<false> {};
};


I can't find anything conclusive in the standard.  I can only see
14.5.1/2 (temp.mem.class) which mentions a class nested in a
template class, but it neither explicitly allows nor forbids a
nested template class.


MSVC++ 6.0 allows it, but Comeau
(http://www.comeaucomputing.com/tryitout/) does not.  Based on past
experience, I'd lean towards trusting Comeau, but my production
environment is MS, and the standard appears to be unclear.
--
Mark Ping
emarkp@soda.CSUA.Berkeley.EDU

---
[ 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.research.att.com/~austern/csc/faq.html                ]





Author: Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr>
Date: Tue, 14 Aug 2001 23:26:35 GMT
Raw View
emarkp@CSUA.Berkeley.EDU (E. Mark Ping) writes:

| That is, is the following code legal?
|
| template <class T> class Outer
| {
|   template <class U> class Inner
|   {
|   };
| };

Yes, the above is well-formed and common practice.

| And if so, then can the inner class be explicitly specialized?
| e.g.:
|
|
| template <class T> class Outer
| {
|   template <bool flag> class Inner;
|   template <> class Inner<true> {};
|   template <> class Inner<false> {};
| };

No, it is ill-formed: a declaration of an explicit specialization
caanot appear at class-scope:

14.7.3/2
  An explicit specialization shall be declared in the namespace of
  which the template is a member, or, for member templates, in the
  namespace of which the enclosing class or enclosing class template
  is member. An explicit specialization of a member function, member
  class or static data member of a class template shall be declared in
  the namespace of which the class template is a member. Such a
  declaration may also be a definition. If the declaration is not a
  definition, the specialization may be defined later in the
  name-space in which the explicit specialization was declared, or in
  a namespace that encloses the one in which the explicit
  specialization was declared.

--
Gabriel Dos Reis, dosreis@cmla.ens-cachan.fr

---
[ 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.research.att.com/~austern/csc/faq.html                ]





Author: emarkp@CSUA.Berkeley.EDU (E. Mark Ping)
Date: Wed, 15 Aug 2001 17:24:24 GMT
Raw View
In article <flitfqqsrz.fsf@pizza.cmla.ens-cachan.fr>,
Gabriel Dos Reis  <dosreis@cmla.ens-cachan.fr> wrote:
[snip]
>14.7.3/2

Ahhh.. Thanks for the help, and the quick response.


--
Mark Ping
emarkp@soda.CSUA.Berkeley.EDU

---
[ 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.research.att.com/~austern/csc/faq.html                ]





Author: Martin Sebor <sebor@roguewave.com>
Date: Thu, 16 Aug 2001 00:59:44 GMT
Raw View
Gabriel Dos Reis wrote:
>
...
> | And if so, then can the inner class be explicitly specialized?
> | e.g.:
> |
> |
> | template <class T> class Outer
> | {
> |   template <bool flag> class Inner;
> |   template <> class Inner<true> {};
> |   template <> class Inner<false> {};
> | };
>
> No, it is ill-formed: a declaration of an explicit specialization
> caanot appear at class-scope:
>
> 14.7.3/2
>   An explicit specialization shall be declared in the namespace of
>   which the template is a member, or, for member templates, in the
>   namespace of which the enclosing class or enclosing class template
>   is member. An explicit specialization of a member function, member
>   class or static data member of a class template shall be declared in
>   the namespace of which the class template is a member. Such a
>   declaration may also be a definition. If the declaration is not a
>   definition, the specialization may be defined later in the
>   name-space in which the explicit specialization was declared, or in
>   a namespace that encloses the one in which the explicit
>   specialization was declared.

This rule, unfortunately, along with 14.7.3, p17, makes it impossible
to define explicit specializations of template members of class templates
without also specializing the enclosing template. To work around it, one
has to either move the nested template to namespace scope, which breaks
encapsulation, or unnecessarily introduce partial specialization.

I.e., this is ill-formed

    template <class T>
    struct A {
        template <class U>
        struct B { };
    };

    template <class T>
    template <>
    A<T>::B<int> { };

I'm curious what the rationale for this is, especially since partial
specializations are allowed to be defined in either scope (i.e., class
or the enclosing namespace).

Martin

---
[ 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.research.att.com/~austern/csc/faq.html                ]