C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Specialization of template members of template classes

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language, library and standards
View previous topic :: View next topic  
Author Message
Ivan Godard
Guest





PostPosted: Thu May 13, 2004 3:36 am    Post subject: Specialization of template members of template classes Reply with quote



This seems too esoteric to draw a response on comp.lang.c++.moderated,
trying here.

Consider:

template<typename A> struct B {
template<typename C> struct D {};
template<> struct D<signed char> { typedef signed short R; };
template<> struct D<unsigned char> { typedef unsigned short R; };
template<> struct D<signed short> { typedef signed int R; };
template<> struct D<unsigned short> { typedef unsigned int R; };
typename D<A>::R v;
};

The purpose is to have a local template that does some type computation
(here to return the type next larger than its argument) which is then used
in the enclosing class, by providing specializations of the local class that
address all argument types of interest. Note that the local template has no
dependence on the enclosing template B nor its argument A. This fails to
compile; g++ complains that you can't specialize a local template inside a
class.

So you move all the specializations outside:

template<typename A> struct B {
template<typename C> struct D {};
typename D<A>::R v;
};
template<> template<typename T>struct B<T>:Very Happy<signed char> { typedef signed
short R; };
template<> template<typename T>struct B<T>::Dstruct B<unsigned char> {
typedef unsigned short R; };
template<> template<typename T>struct B<T>::Dstruct B<signed short> {
typedef signed int R; };
template<> template<typename T>struct B<T>::Dstruct B<unsigned short> {
typedef unsigned int R; };

This too fails to compile; g++ complains that the specialization does not
depend on T.

I reported these as bugs to g++, and they assert that the behavior is
correct by the standard. I'm willing to believe that, but would like to know
why the standard bans this construction, which seems straightforward,
useful, and easy to compile. Also, is there an alternative formulation that
achieves the desired goal? (Yes, the template D and its specializations can
be moved to file scope, which is my present workaround, but that pollutes
the
namespace.)

Ivan

---
[ 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 ]

Back to top
Daniel Krügler
Guest





PostPosted: Thu May 13, 2004 10:29 am    Post subject: Re: Specialization of template members of template classes Reply with quote



Good morning, Ivan Godard,

Ivan Godard schrieb:
[..]

Quote:
So you move all the specializations outside:

template<typename A> struct B {
template<typename C> struct D {};
typename D<A>::R v;
};
template<> template<typename T>struct B<T>:Very Happy<signed char> { typedef signed
short R; };
template<> template<typename T>struct B<T>::Dstruct B<unsigned char> {
typedef unsigned short R; };
template<> template<typename T>struct B<T>::Dstruct B<signed short> {
typedef signed int R; };
template<> template<typename T>struct B<T>::Dstruct B<unsigned short> {
typedef unsigned int R; };

This too fails to compile; g++ complains that the specialization does not
depend on T.

I reported these as bugs to g++, and they assert that the behavior is
correct by the standard. I'm willing to believe that, but would like to know
why the standard bans this construction, which seems straightforward,
useful, and easy to compile. Also, is there an alternative formulation that
achieves the desired goal? (Yes, the template D and its specializations can
be moved to file scope, which is my present workaround, but that pollutes
the
namespace.)


I think the reason for banning this construction is due to the fact,

that you have to consider, that potentially
everyone could (partially) specialize the class template B. Now, if you
realize that such a specialization could
remove any member class templates D (or substitute them by other items
of name D) you will understand,
that in those cases the compiler would have a problem. I think the
problem could be solved by an ordering
mechanism (lets say, any outer specializations overwrites inner
specializations) but I don't know whether this
would not lead to other problems...)

Hope that helps,

Daniel


---
[ 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 ]


Back to top
Alberto Barbati
Guest





PostPosted: Thu May 13, 2004 10:29 am    Post subject: Re: Specialization of template members of template classes Reply with quote



Ivan Godard wrote:
Quote:
I reported these as bugs to g++, and they assert that the behavior is
correct by the standard. I'm willing to believe that, but would like to know
why the standard bans this construction, which seems straightforward,
useful, and easy to compile.

It does not look so straightforward, useful and easy to compile, to me.
Just my opinion, though ;-)

Quote:
Also, is there an alternative formulation that
achieves the desired goal? (Yes, the template D and its specializations can
be moved to file scope, which is my present workaround, but that pollutes
the namespace.)

What about:

namespace B_details {
template<typename C> struct D {};
template<> struct D<signed char> { typedef signed short R; };
template<> struct D<unsigned char> { typedef unsigned short R; };
template<> struct D<signed short> { typedef signed int R; };
template<> struct D<unsigned short> { typedef unsigned int R; };
};

template<typename A> struct B {
typename B_details:Very Happy<A>::R v;
};

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 ]


Back to top
Richard Smith
Guest





PostPosted: Thu May 13, 2004 3:14 pm    Post subject: Re: Specialization of template members of template classes Reply with quote

[email]igodardA (AT) TpacbellDO (DOT) Tnet[/email] ("Ivan Godard") wrote in message news:<caAoc.47757$ur3.7396 (AT) newssvr29 (DOT) news.prodigy.com>...
Quote:
This seems too esoteric to draw a response on comp.lang.c++.moderated,
trying here.

Consider:

template<typename A> struct B {
template<typename C> struct D {};
template<> struct D<signed char> { typedef signed short R; };

This is not legal for two reasons. First, explicit specialisations
may not be declared at class scope (some compilers do accept them,
however). (See 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 a member.")

Second, you can only expicitly specialise a member template for a
specific instantiation of the (outer) template class. That is, if you
want to specialise B<A>:Very Happy<C> for some C, you must also do it for a
specified A too.

If you want to specialise B<int>:Very Happy<signed char>, the declaration
would look like this:

template <> template <>
struct B<int>:Very Happy<signed char> {
typedef signed short R;
};

If you need to constrain C but not A, then you will have to use
another mechanism, for example delegating to a namespace scope
template:

namespace Details {
template <typename A, typename C> struct B_D {};
}
template<typename A> struct B {
template<typename C> struct D : Details::B_D<A,C> {};
}

// Specialisations go here:
namespace Details {
template <typename A> struct B_D<A, signed char> {
typedef signed short R;
};
}

Quote:
Note that the local template has no
dependence on the enclosing template B nor its argument A.

So why is it a member template? (Note: the term is member template,
not local template.) By making it a member template, you get a
separate instantiation for each pair (A,C); if the value of A is
irrelevant, this will likely lead to code bloat.

Quote:
This fails to
compile; g++ complains that you can't specialize a local template inside a
class.

As indeed it should.

Quote:
So you move all the specializations outside:

template<typename A> struct B {
template<typename C> struct D {};
typename D<A>::R v;
};
template<> template<typename T>struct B<T>:Very Happy<signed char> { typedef signed
short R; };
[...]
This too fails to compile; g++ complains that the specialization does not
depend on T.

Again, quite correctly for the second reason I mentioned above. You
also have the wrong syntax. Were what you want to do legal, I *think*
the syntax would be as follows:

template <typename T> template <>
struct B<T>:Very Happy<signed char> { /* ... */ };

This question, and many related issues, are covered in Vandevoorde and
Josuttis' definitive book "C++ Templates: The Complete Guide".
Section 12.3 covers this particular issue. I stongly recommend
obtaining a copy.

Quote:
I'm willing to believe that, but would like to know
why the standard bans this construction, which seems straightforward,
useful, and easy to compile.

Straightforward? That's not the word I would have used.

As to whether it's "easy to compile", it would add various extra
complications to do with partial ordering. For example, if I have two
specialisations,

template <> template <class C>
struct B<int>:Very Happy { enum {I=2}; };

template <class A> template <>
struct B<A>:Very Happy<signed char> { enum {I=3}; };

Now, what is B<int>:Very Happy<signed char>::I? I would probably expect it
to be 2, as I would expect the specialisation of B<int>:Very Happy to replace
both the primary template B<A>:Very Happy and all its specialisations; but
equally, others might expect partial ordering to flag an ambiguity in
this case.

Resolving this would require extra complication in an already complex
section of the Standard as well as additional inteligence in the
compiler. Frankly, I can't see the worth of it.

--
Richard Smith

---
[ 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 ]


Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language, library and standards All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.