By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
449,264 Members | 1,763 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 449,264 IT Pros & Developers. It's quick & easy.

Nested template specialization?

P: n/a
Can anyone lend a hand on getting this particular template
specialization working? I've been trying to compile with g++ 4.1 and
VS 2005.

//------------------------------------------------------------------

// my regular glass
class A { };

// my templated class
template < typename T class B { };

// this is a library class with a library function i want to
specialize for my classes
template < typename T >
class C
{
public:
void func ( T arg )
{
fprintf( stderr, "C< T >\n" );
}
};

// specialization on A works just fine
template < >
void C< A >::func ( A arg )
{
fprintf( stderr, "C< A >\n" );
};

// specialization on B<Tfails to compile
template < typename T >
void C< B< T ::func ( B< T arg )
{
fprintf( stderr, "C< B< T \n" );
};

//------------------------------------------------------------------

The motivation for this is I have a templated class that has
particular memory allocation requirements (I need it to be aligned),
that I'd like to be able to use with STL containers without having to
pass in a custom allocator every time. So I'm trying to overload
std::allocator's allocate and deallocate member functions to work on
my template class. I'm afraid this is a funny form of partial
specialization of a function and I'm just out of luck, but maybe
there's a workaround? I'm sure other people have had similar
difficulties...Thanks,

-stephen diverdi
-s**************@gmail.com

Sep 12 '07 #1
Share this Question
Share on Google+
9 Replies


P: n/a
st*************@gmail.com wrote:
Can anyone lend a hand on getting this particular template
specialization working? I've been trying to compile with g++ 4.1 and
VS 2005.

//------------------------------------------------------------------

// my regular glass
class A { };

// my templated class
template < typename T class B { };

// this is a library class with a library function i want to
specialize for my classes
template < typename T >
class C
{
public:
void func ( T arg )
{
fprintf( stderr, "C< T >\n" );
}
};

// specialization on A works just fine
template < >
void C< A >::func ( A arg )
{
fprintf( stderr, "C< A >\n" );
};

// specialization on B<Tfails to compile
template < typename T >
void C< B< T ::func ( B< T arg )
{
fprintf( stderr, "C< B< T \n" );
};

//------------------------------------------------------------------

The motivation for this is I have [..valid reason..]
I'm afraid this is a funny form of partial
specialization of a function and I'm just out of luck, but maybe
there's a workaround? I'm sure other people have had similar
difficulties...Thanks,
It's not "a funny form of partial specialization of a function".
It's a prohibited attempt to specialise a member without first
specialising the class template. You need to specialise C<B<T>>
first and declare that it does have the same 'func' member.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Sep 12 '07 #2

P: n/a
st*************@gmail.com wrote:
Can anyone lend a hand on getting this particular template
specialization working? I've been trying to compile with g++ 4.1 and
VS 2005.

//------------------------------------------------------------------

// my regular glass
class A { };

// my templated class
template < typename T class B { };

// this is a library class with a library function i want to
specialize for my classes
template < typename T >
class C
{
public:
void func ( T arg )
{
fprintf( stderr, "C< T >\n" );
}
};

// specialization on A works just fine
template < >
void C< A >::func ( A arg )
{
fprintf( stderr, "C< A >\n" );
};

// specialization on B<Tfails to compile
template < typename T >
void C< B< T ::func ( B< T arg )
{
fprintf( stderr, "C< B< T \n" );
};

//------------------------------------------------------------------

The motivation for this is I have a templated class that has
particular memory allocation requirements (I need it to be aligned),
that I'd like to be able to use with STL containers without having to
pass in a custom allocator every time. So I'm trying to overload
std::allocator's allocate and deallocate member functions to work on
my template class. I'm afraid this is a funny form of partial
specialization of a function and I'm just out of luck, but maybe
I guess it is.
there's a workaround? I'm sure other people have had similar
you have to partial specialize the whole class

template < typename T >
class C <B<T{
public:
void C< B< T ::func ( B< T arg )
{
fprintf( stderr, "C< B< T \n" );
}

};

yah, then have much more work to do with the rest of members.
difficulties...Thanks,
--
Thanks
Barry
Sep 12 '07 #3

P: n/a
Barry wrote:
st*************@gmail.com wrote:
>Can anyone lend a hand on getting this particular template
specialization working? I've been trying to compile with g++ 4.1 and
VS 2005.

//------------------------------------------------------------------

// my regular glass
class A { };

// my templated class
template < typename T class B { };

// this is a library class with a library function i want to
specialize for my classes
template < typename T >
class C
{
public:
void func ( T arg )
{
fprintf( stderr, "C< T >\n" );
}
};

// specialization on A works just fine
template < >
void C< A >::func ( A arg )
{
fprintf( stderr, "C< A >\n" );
};

// specialization on B<Tfails to compile
template < typename T >
void C< B< T ::func ( B< T arg )
{
fprintf( stderr, "C< B< T \n" );
};

//------------------------------------------------------------------

The motivation for this is I have a templated class that has
particular memory allocation requirements (I need it to be aligned),
that I'd like to be able to use with STL containers without having to
pass in a custom allocator every time. So I'm trying to overload
std::allocator's allocate and deallocate member functions to work on
my template class. I'm afraid this is a funny form of partial
specialization of a function and I'm just out of luck, but maybe

I guess it is.
>there's a workaround? I'm sure other people have had similar

you have to partial specialize the whole class

template < typename T >
class C <B<T{
public:
void C< B< T ::func ( B< T arg )
just copy your code
should be:

void C::func ( B< T arg )
{
fprintf( stderr, "C< B< T \n" );
}

};

yah, then have much more work to do with the rest of members.
>difficulties...Thanks,

--
Thanks
Barry
Sep 12 '07 #4

P: n/a
>
It's not "a funny form of partial specialization of a function".
It's a prohibited attempt to specialise a member without first
specialising the class template. You need to specialise C<B<T>>
first and declare that it does have the same 'func' member.
Hmm, so why don't I need to specialize C<Afirst before creating
the specialized C<A>::func implementation?

And as it relates to my motivation, your answer means I'm going
to have to copy the entire implementation of std::allocator and
specialize every member functionf or C<B<T>>?

Thanks,

-stephen diverdi
-s**************@gmail.com

Sep 12 '07 #5

P: n/a
st*************@gmail.com wrote:
>It's not "a funny form of partial specialization of a function".
It's a prohibited attempt to specialise a member without first
specialising the class template. You need to specialise C<B<T>>
first and declare that it does have the same 'func' member.
Hmm, so why don't I need to specialize C<Afirst before creating
the specialized C<A>::func implementation?

Because with C<A>::func it's an explicit *full* specialisation,
which triggers an implicit instantiation of C<A>.
And as it relates to my motivation, your answer means I'm going
to have to copy the entire implementation of std::allocator and
specialize every member functionf or C<B<T>>?

Yes, if you want the precisely same layout, behaviour, etc. Of
course, you could simply extract the function in question into
a separate class and specialise only it (and then derive from it)
thus saving some typing...

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Sep 12 '07 #6

P: n/a
>
I am not sure I understand. What would drive the language creators
to specify the partial specialisation "more like" inheritance when you
can accomplish the same thing with inheritance, while NOT specifying
it "more like" inheritance actually gives you more freedom?
The entire idea behind templates (unless I've misunderstood) is to
avoid
having to specify the API and implementation for separate classes that
have fundamentally the same behavior, just parameterized on a few
basic
arguments (type, int, etc.). If I want to make an array class that
operates on int's, float's, and MyClass's, without templates I have to
write all three, whereas with templates, I write once.

I expected that partial specialization would attempt to further that
same
goal, but the fact that the entire class needs to be redefined for
each
partial specialization seems to directly contradict the original goal
of templates.

In the end, writing separate classes for every case gives you the most
freedom, so why have templates at all?

And while I said "inheritance-like", clearly templates and inheritance
serve different (orthogonal?) purposes. You could not use inheritance
to, e.g., implement a class (or set of classes) that mimiced the API
behavior of STL's vector.
Besides,
the biggest pitfall of allowing the partial specialisation work that
way is that any changes in the original template suddenly would be
propagated into all partially specialised ones without even a notice
or a warning.
That's actually exactly the advantage of such an approach. If I make
a
change to my template, I don't want to have to propogate that change
into
every partial specialization manually, as that generates a lot more
work
and increases the potential for bugs.

Analogously, if you make a change to a base class, all the classes
that
inherit from it are updated without notice or warning. Do you think
that's
a bad thing?
Also, partial specialisaion is often used to change the structure and
behaviour of a template for, say, all pointers, in which case allowing
"inheritance" is more headache than gain. IMHO.
Behavior, yes, I agree. Structure? Do people use partial
specialization
to make API changes to their classes? That seems like bad practice.
How
confusing would it be to look at a template class definition,
instantiate
an object with some template arguments, and then find out it has a
totally
different API because you didn't notice that in another header there's
a
partial specialization that completely redefines it?
-stephen diverdi
-s**************@gmail.com

Sep 13 '07 #7

P: n/a
st*************@gmail.com wrote:
>I am not sure I understand. What would drive the language creators
to specify the partial specialisation "more like" inheritance when
you can accomplish the same thing with inheritance, while NOT
specifying it "more like" inheritance actually gives you more
freedom?

The entire idea behind templates (unless I've misunderstood) is to
avoid
having to specify the API and implementation for separate classes that
have fundamentally the same behavior, just parameterized on a few
basic
arguments (type, int, etc.). If I want to make an array class that
operates on int's, float's, and MyClass's, without templates I have to
write all three, whereas with templates, I write once.

I expected that partial specialization would attempt to further that
same
goal, but the fact that the entire class needs to be redefined for
each
partial specialization seems to directly contradict the original goal
of templates.

In the end, writing separate classes for every case gives you the most
freedom, so why have templates at all?
Yes, you do sound confused.

The fact that you can partially specialise a template thus extracting
a whole (usually infinite) subset of (usually infinite) specialisations
and define them differently (than the original template) does *not*
contradict the purpose of templates at all. Actually, it affirms it.

If I have to guess, it's the word "specialisation" that confuses you.
A partial specialisation is effectively a *different* template, and
the only thing that ties them together is the name, which can be used
elsewhere by somebody who doesn't want to concern himself with how
many different "specialisations" the compiler knows about.
And while I said "inheritance-like", clearly templates and inheritance
serve different (orthogonal?) purposes.
Undoubtedly.
You could not use inheritance
to, e.g., implement a class (or set of classes) that mimiced the API
behavior of STL's vector.
I am not sure how this is relevant here.
>
>Besides,
the biggest pitfall of allowing the partial specialisation work that
way is that any changes in the original template suddenly would be
propagated into all partially specialised ones without even a notice
or a warning.
That's actually exactly the advantage of such an approach. If I make
a
change to my template, I don't want to have to propogate that change
into
every partial specialization manually, as that generates a lot more
work
and increases the potential for bugs.

Analogously, if you make a change to a base class, all the classes
that
inherit from it are updated without notice or warning. Do you think
that's
a bad thing?
No, but that's the purpose of the inheritance mechanism. Why have
two mechanisms that have exactly the same effect in the language?
That's what I mean by the freedom. The more mechanisms with different
effects you have, the more choices you have when trying to accomplish
your goal.

The effect you want is attainable using inheritance. Partial template
specialisation is *not* going to help. Why do you keep expressing
the desire to use partial specialisation to do what inheritance is
designed to do?
>Also, partial specialisaion is often used to change the structure and
behaviour of a template for, say, all pointers, in which case
allowing "inheritance" is more headache than gain. IMHO.
Behavior, yes, I agree. Structure? Do people use partial
specialization
to make API changes to their classes? That seems like bad practice.
I don't know what you're talking about, and am not going to guess.
How
confusing would it be to look at a template class definition,
instantiate
an object with some template arguments, and then find out it has a
totally
different API because you didn't notice that in another header there's
a
partial specialization that completely redefines it?
Probably not the effect you want, but if you know that that's not
desirable, don't make it so.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Sep 13 '07 #8

P: n/a
If I have to guess, it's the word "specialisation" that confuses you.
A partial specialisation is effectively a *different* template, and
the only thing that ties them together is the name, which can be used
elsewhere by somebody who doesn't want to concern himself with how
many different "specialisations" the compiler knows about.
Please explain to me then what is the advantage of creating a partial
specialization versus creating an entirely separate template class
then?
>
You could not use inheritance
to, e.g., implement a class (or set of classes) that mimiced the API
behavior of STL's vector.

I am not sure how this is relevant here.
I was replying to your statement in a previous post that "you can
accomplish the same thing with inheritance", which you seem to be
making again in this post. This is categorically false.
>
No, but that's the purpose of the inheritance mechanism. Why have
two mechanisms that have exactly the same effect in the language?
That's what I mean by the freedom. The more mechanisms with different
effects you have, the more choices you have when trying to accomplish
your goal.
Templates provide a way to parameterize aspects your class definition,
while inheritance provides a way for objects to assume the properties
of many different related types at run time. The way templates and
inheritance differ is separate from the way partial specialization is
handled, as compared to subclassing. Even if partial specialization
of templates propogated APIs the same way inheritance does, they would
still be fundamentally different constructs and would still serve
fundamentally different purposes.
The effect you want is attainable using inheritance. Partial template
specialisation is *not* going to help. Why do you keep expressing
the desire to use partial specialisation to do what inheritance is
designed to do?
Please propose a way create a set of vector classes using
inheritance. I would like one class for each combination of
{int,float,double} and {2,3,4}-dimensions. They should all have the
same API, though the implementations for the different dimensions will
differ (for performance reasons). I would also like compile-time
typechecking and conversion for operations among these types.
>
I don't know what you're talking about, and am not going to guess.
You seem to be suggesting that people regularly use partial
specialization to do something along these lines:

template < int N, typename T >
class MyClass {
T vals[ N ];
T func () const;
};

template < typename T >
class MyClass< 4, T {
T vals[ 4 ];
T different_func () const;
};

That looks like a pretty bad design to me - a user would have no
reason to expect that the set of member functions in MyClass< 4, float
would be totally different from the set in MyClass< 3, double >,
without exhaustively searching through all the headers to make sure
they've found all the possible specializations.
-stephen diverdi
-s**************@gmail.com

Sep 13 '07 #9

P: n/a
st*************@gmail.com wrote:
>If I have to guess, it's the word "specialisation" that confuses you.
A partial specialisation is effectively a *different* template, and
the only thing that ties them together is the name, which can be used
elsewhere by somebody who doesn't want to concern himself with how
many different "specialisations" the compiler knows about.
Please explain to me then what is the advantage of creating a partial
specialization versus creating an entirely separate template class
then?
WTF do you mean? A separate class template cannot have the same name,
so if your class template is used somewhere and referred by its name,
having a separate class template is non-sensical. So, the advantage is
that you can accomplish something with a template specialisation which
you can't accomplish with ANYTHING ELSE.
>> You could not use inheritance
to, e.g., implement a class (or set of classes) that mimiced the API
behavior of STL's vector.

I am not sure how this is relevant here.
I was replying to your statement in a previous post that "you can
accomplish the same thing with inheritance", which you seem to be
making again in this post. This is categorically false.
Again, I have no idea what you mean and thus I don't see any relevance.
>No, but that's the purpose of the inheritance mechanism. Why have
two mechanisms that have exactly the same effect in the language?
That's what I mean by the freedom. The more mechanisms with
different effects you have, the more choices you have when trying to
accomplish your goal.
Templates provide a way to parameterize aspects your class definition,
while inheritance provides a way for objects to assume the properties
of many different related types at run time. The way templates and
inheritance differ is separate from the way partial specialization is
handled, as compared to subclassing. Even if partial specialization
of templates propogated APIs the same way inheritance does, they would
still be fundamentally different constructs and would still serve
fundamentally different purposes.
I am now not sure you understood my initial suggestion, or perhaps its
meaning has mutated in your mind since we started this debate, but it
seems that you just don't [want to] see what I was suggesting and why
I was suggesting it. Too bad.
>The effect you want is attainable using inheritance. Partial
template specialisation is *not* going to help. Why do you keep
expressing the desire to use partial specialisation to do what
inheritance is designed to do?
Please propose a way create a set of vector classes using
inheritance. I would like one class for each combination of
{int,float,double} and {2,3,4}-dimensions. They should all have the
same API, though the implementations for the different dimensions will
differ (for performance reasons). I would also like compile-time
typechecking and conversion for operations among these types.
Do your own development, will you? I am not going to solve all the
problems you have, but in the example that started this discussion
you _can_ put the *common* functionality in a base class and put the
*different* functionality in each of the specialisations *without*
requiring that specialisation mechanism provides *inheritance* of
the behaviour you don't want to change.
>I don't know what you're talking about, and am not going to guess.
You seem to be suggesting that people regularly use partial
I am not suggesting what "people regularly use" any C++ mechanisms
for. I can only attest to what *I* use them for. I can *suggest*
what others *might what to consider* using some C++ mechanisms for.
What everybody does in their development it's up to them.
specialization to do something along these lines:

template < int N, typename T >
class MyClass {
T vals[ N ];
T func () const;
};

template < typename T >
class MyClass< 4, T {
T vals[ 4 ];
T different_func () const;
};

That looks like a pretty bad design to me - a user would have no
reason to expect that the set of member functions in MyClass< 4, float
>would be totally different from the set in MyClass< 3, double >,
without exhaustively searching through all the headers to make sure
they've found all the possible specializations.
You're twisting my arguments and pulling your examples "by the ears"
to suit your point of view. I never suggested that a specialisation
*should* have a different interface. It is entirely up to you, the
interface designer.

What I do suggest is, if you have to have a common _interface_ in
all specialisations of your template, plus you need some different
behaviour, instead of *requesting* the language to change to suit
your needs you use the mechanism provided. Here is the example:

template<class Tclass Foo {
void dosomething() {}
static std::size_t get_id() { return glb_reg(Foo); }
};

template<class Tclass Foo<T*{ // partial specialisation
void dosomething() {}
static std::size_t get_id() { return ptr_reg(Foo); }
};

According to you, the partial specialisation should allow one to
omit defining 'dosomething' in the second 'Foo' template:

template<class Tclass Foo {
void dosomething() {}
static std::size_t get_id() { return glb_reg(Foo); }
};

template<class Tclass Foo<T*{ // partial specialisation
// void dosomething() {} "inherited"
static std::size_t get_id() { return ptr_reg(Foo); }
};

What I am saying is that it shouldn't since a solution is available
using the inheritance mechanism:

template<class Tclass Foo_Base {
void dosomething() {}
};

template<class Tclass Foo : Foo_Base<T{
// void dosomething() {} inherited here
static std::size_t get_id() { return glb_reg(Foo); }
};

template<class Tclass Foo<T*: Foo_Base<T*{ // partial
specialisation
// void dosomething() {} inherited here as well
static std::size_t get_id() { return ptr_reg(Foo); }
};

Do you get it now?
V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Sep 14 '07 #10

This discussion thread is closed

Replies have been disabled for this discussion.