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 

Where are member specializations allowed?

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





PostPosted: Wed Nov 08, 2006 3:47 pm    Post subject: Where are member specializations allowed? Reply with quote



Hallo,
If my reading of the standard is correct, member template partial
specializations may be defined within the enclosing class definition,
while member template explicit specializations may not. I base my
conclusions on clause 14.7.3-2 which says:
"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. 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 namespace in which the explicit
specialization was declared, or in a namespace that encloses the one in
which the explicit specialization was declared."

I wasn't unable to find similar text for partial specializations and
the example in clause 14.5.4.3-2:

template<class T> struct A {
template<class T2> struct B {}; // #1
template<class T2> struct B<T2*> {}; // #2
};
template<> template<class T2> struct A<short>::B {}; // #3

appears to support my understanding. Is this difference intentional and
if it is, what is the rationale behind it?

On a related note, why are explicit specializations of member templates
of non specialized class templates forbidden?

Cheers,
Nicola Musatti

---
[ 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.comeaucomputing.com/csc/faq.html ]
Back to top
Greg Herlihy
Guest





PostPosted: Thu Nov 09, 2006 5:44 pm    Post subject: Re: Where are member specializations allowed? Reply with quote



Nicola Musatti wrote:
Quote:
If my reading of the standard is correct, member template partial
specializations may be defined within the enclosing class definition,
while member template explicit specializations may not. I base my
conclusions on clause 14.7.3-2 which says:
...
I wasn't unable to find similar text for partial specializations and
the example in clause 14.5.4.3-2:

template<class T> struct A {
template<class T2> struct B {}; // #1
template<class T2> struct B<T2*> {}; // #2
};
template<> template<class T2> struct A<short>::B {}; // #3

appears to support my understanding. Is this difference intentional and
if it is, what is the rationale behind it?

The difference is far more likely to be incidental - rather than
intentional. In other words, there probably is no rationale that
requires partial and full member specializations to be declared in
disinct locations. There probably is a deliberate intention to have any
kind of declaration appear at the location where it makes the most
sense for a declaration of that kind to be placed. So it is the
consequence of that rationale that no doubt accounts for the difference
here.

After all, it simply makes more sense for the declaration of a partial
specialization of a member template to appear within its enclosing
class template (since the partial specialization is reproduced in each
instantiation of the class template). Likewise, it also makes sense for
a full member specialzation to be declared outside of any other
template - by itself - since a full specialization describes a unique
type that stands on its own.

Quote:
On a related note, why are explicit specializations of member templates
of non specialized class templates forbidden?

Since a member class template is a distinct template for each of its
enclosing class template instantiations, being able to declare a full
member specialization without an enclosinig class template
specialization, would specialize - not just one member class template -
but would in fact specialize an unlimited number of member class
templates that would "cut across" the specializations of its enclosing
class template. The member template would in effect be creating
specializations of its enclosing class template that its enclosing
class template would not itself be specializing.

In effect, allowing a member template specialization by itself would
mean that a member template could be specialized on either of two,
different axes. And having two different ways to specialize the same
template simply invites ambiguity and conflict - and would add no new
capability to C++ templates in return. So while there are good
arguments for making C++ templates more capable, there is no argument
to be made for making them merely more complex.

Greg

---
[ 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.comeaucomputing.com/csc/faq.html ]
Back to top
Simon G Best
Guest





PostPosted: Sun Dec 31, 2006 12:42 am    Post subject: Re: Where are member specializations allowed? Reply with quote



Hello!

Recently, I tried to do the following:-

[Start C++ snippet here.]

template<typename T> class thingy {
public:
template<typename U> T f (const U &) const;
};

// The general case:-
template<typename T> template<typename U> T thingy<T>::f
(const U &x) const {
return T(x);
}

// The special case:-
template<typename T> template<> T thingy<T>::f<T> (const T &x) const {
return x;
}

[End C++ snippet here.]

and it didn't work. I gather it's Not Allowed:-

Greg Herlihy wrote:
Quote:
Nicola Musatti wrote:
[...]
On a related note, why are explicit specializations of member templates
of non specialized class templates forbidden?

Since a member class template is a distinct template for each of its
enclosing class template instantiations, being able to declare a full
member specialization without an enclosinig class template
specialization, would specialize - not just one member class template -
but would in fact specialize an unlimited number of member class
templates that would "cut across" the specializations of its enclosing
class template. The member template would in effect be creating
specializations of its enclosing class template that its enclosing
class template would not itself be specializing.

In effect, allowing a member template specialization by itself would
mean that a member template could be specialized on either of two,
different axes. And having two different ways to specialize the same
template simply invites ambiguity and conflict - and would add no new
capability to C++ templates in return. So while there are good
arguments for making C++ templates more capable, there is no argument
to be made for making them merely more complex.

I'm not convinced; it sounds a bit confused. The enclosing template and
the member template are clearly distinct, aren't they?

Anyway, I found that I could get something like what I wanted by doing
the following:-

[Start C++ snippet here.]

template<typename T> class thingy {
public:
template<typename U> T f (const U &) const;
};

namespace {

// The general case:-
template<typename T, typename U> class thingy_f_implementation {
public:
static T f (const U &x) { return T(x); }
};

// The special case:-
template<typename T> class thingy_f_implementation<T, T> {
public:
static T f (const T &x) { return x; }
};
}

template<typename T> template<typename U> T thingy<T>::f (const U &x)
const {
return thingy_f_implementation<T, U>::f(x);
}

[End C++ snippet here.]

It works, but does involve having that class thingy_f_implementation<>,
even if it's in an anonymous namespace. (If it's in a header (specially
as 'export' is often unimplemented), it'll get included in everything
that #includes that header.) But it does leave the interface of class
thingy<> unchanged, which seems right when the specialisation is only
for implementational reasons.

I'd really rather do it the way I originally tried, though. I don't yet
see how allowing such specialisations would lead to ambiguities, so if
someone could post an example to enlighten me, I'd appreciate it :-)

Simon

--
What happens if I mention Leader Kibo in my .signature?

---
[ 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.comeaucomputing.com/csc/faq.html ]
Back to top
Greg Herlihy
Guest





PostPosted: Tue Jan 02, 2007 6:00 pm    Post subject: Re: Where are member specializations allowed? Reply with quote

Simon G Best wrote:
Quote:
Recently, I tried to do the following:-

template<typename T> class thingy {
public:
template<typename U> T f (const U &) const;
};

// The general case:-
template<typename T> template<typename U> T thingy<T>::f
(const U &x) const {
return T(x);
}

// The special case:-
template<typename T> template<> T thingy<T>::f<T> (const T &x) const {
return x;
}

and it didn't work. I gather it's Not Allowed:-

No, that's Not Allowed - but this is:

template<typename T>
class thingy
{
public:
T f(const T& t) const;

template<typename U>
T f(const U& u) const;
};

// The general case:
template<typename T>
template<typename U>
T thingy<T>::f( const U& u) const
{
return T(u);
}

// The "special" case:
template<typename T>
T thingy<T>::f( const T& t) const
{
return t;
}

One advantage of overloading - instead of specializing - f() is to
extend the "special case" to include calls to f() with argument types
other than T (and T only). The f() overload will also execute whenever
f() is called with an argument of a type derived from T (or a type that
implicitly converts to T). For example, the specialized f() could
handle this call: f(5L) or this one: f(5) but never both (despite the
lack of any meaningful difference between the two calls.) The f()
overload in contrast can handle both calls identically.

Quote:
I'd really rather do it the way I originally tried, though. I don't yet
see how allowing such specialisations would lead to ambiguities, so if
someone could post an example to enlighten me, I'd appreciate it Smile

The original example faces a more immediate obstacle: namely that C++
does not allow function templates to be partially specialized. In other
words, it is not possible to provide a definition of the function
template f() that handles just the case when f()'s type parameter and
the type parameter of the thingy specialization of which f() is a
member - are one and the same type.

Now, why C++ does not allow function templates to be partially
specialized, I do not know for sure. I half-believe that the reason is
simply to prevent the rules for resolving overloaded function calls in
C++ from collapsing under the weight of their own complexity. On the
other hand, the C++ Standard is not known for capitulating in the face
of complexity. On the contrary, the Standard at times evinces an almost
boundless tolerance of (or appetite for?) complexity. So I would say
that this question is still quite open.

Greg

---
[ 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.comeaucomputing.com/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.