Specialization of Member functions

P

Patrick Kutch

Please take a look at the following code snippit:
-------------------------------------------------------
template<class TraitClass=int>
class TestClass
{
public:
void CallFunc()
{
SpecializedFunct_<TraitClass>();
}

private:
template<class TraitClass >
void SpecializedFunct_(void)
{
// called for non-specialized
}

template<>
void SpecializedFunct_<int>(void)
{
// specialized for TraitClass=int
}

template<>
void SpecializedFunct_<char>(void)
{
// specialized for TraitClass=char
}
};
-------------------------------------------------------

It works GREAT with Visual Studio .NET 2003. Complains to high-heaven with
the gcc 3.2.2 compiler that came with Red Hat Linux 9.0.

I have done some digging and found a few blurbs in my google-mining that
says something to the effect that specialization of member functions for a
non-specialized class is not supported.

So I have 2 questions:

1. Has the standard changed and MS is on the ball, or is it a MS compiler
extension that allows this to work?

2. Would greatly appreciate suggestions on how to get around this issue, I
really really would like to have specialized member functions.

thanx!
 
S

Slawomir Lisznianski

Patrick said:
Please take a look at the following code snippit:
-------------------------------------------------------
template<class TraitClass=int>
class TestClass
{
public:
void CallFunc()
{
SpecializedFunct_<TraitClass>();
}

private:
template<class TraitClass >
void SpecializedFunct_(void)
{
// called for non-specialized
}

template<>
void SpecializedFunct_<int>(void)
{
// specialized for TraitClass=int
}

template<>
void SpecializedFunct_<char>(void)
{
// specialized for TraitClass=char
}
};
-------------------------------------------------------

It works GREAT with Visual Studio .NET 2003. Complains to high-heaven with
the gcc 3.2.2 compiler that came with Red Hat Linux 9.0.

I have done some digging and found a few blurbs in my google-mining that
says something to the effect that specialization of member functions for a
non-specialized class is not supported.

So I have 2 questions:

1. Has the standard changed and MS is on the ball, or is it a MS compiler
extension that allows this to work?

2. Would greatly appreciate suggestions on how to get around this issue, I
really really would like to have specialized member functions.

thanx!

Would this work for you?


template<class TraitClass=int>
class TestClass
{
public:
void CallFunc()
{
SpecializedFunct_();
}

private:
void SpecializedFunct_()
{
// called for non-specialized
}
};

template<>
void
TestClass<int>::SpecializedFunct_(void)
{
// specialized for TraitClass=int
}

template<>
void
TestClass<char>::SpecializedFunct_(void)
{
// specialized for TraitClass=char
}


-Slawomir Lisznianski
 
S

Sharad Kala

Patrick Kutch said:
Please take a look at the following code snippit:
-------------------------------------------------------
template<class TraitClass=int>
class TestClass
{
public:
void CallFunc()
{
SpecializedFunct_<TraitClass>();
}

private:
template<class TraitClass >
void SpecializedFunct_(void)
{
// called for non-specialized
}

template<>
void SpecializedFunct_<int>(void)
{
// specialized for TraitClass=int
}

template<>
void SpecializedFunct_<char>(void)
{
// specialized for TraitClass=char
}
};
-------------------------------------------------------

It works GREAT with Visual Studio .NET 2003. Complains to high-heaven with
the gcc 3.2.2 compiler that came with Red Hat Linux 9.0.

I have done some digging and found a few blurbs in my google-mining that
says something to the effect that specialization of member functions for a
non-specialized class is not supported.

So I have 2 questions:

1. Has the standard changed and MS is on the ball, or is it a MS compiler
extension that allows this to work?

I would place my trust with gcc here. I don't think explicit specialization
should work in your case.
2. Would greatly appreciate suggestions on how to get around this issue, I
really really would like to have specialized member functions.

Slawomir has suggested a solution which could work for you.
He specializes the class rather than the member function (Nice way to look at
things differently ;-))

Best wishes,
Sharad
 
P

Patrick Kutch

Slawomir Lisznianski said:
Would this work for you?


template<class TraitClass=int>
class TestClass
{
public:
void CallFunc()
{
SpecializedFunct_();
}

private:
void SpecializedFunct_()
{
// called for non-specialized
}
};

template<>
void
TestClass<int>::SpecializedFunct_(void)
{
// specialized for TraitClass=int
}

template<>
void
TestClass<char>::SpecializedFunct_(void)
{
// specialized for TraitClass=char
}


-Slawomir Lisznianski
I don't believe so. The example is trivial, my actual class has 6 template
parameters - would be rather difficult to specialize all of them.

- Patrick
 
R

Rob Williscroft

Patrick Kutch wrote in
Please take a look at the following code snippit:
-------------------------------------------------------
template<class TraitClass=int>
class TestClass
{
public:
void CallFunc()
{

This is suspect, why wre you passing in the current template's
paramiter, members are already "specialized" on this paramiter.
SpecializedFunct_<TraitClass>();
}

private:
template<class TraitClass >
void SpecializedFunct_(void)
{
// called for non-specialized
}

template<>
void SpecializedFunct_<int>(void)
{
// specialized for TraitClass=int
}

template<>
void SpecializedFunct_<char>(void)
{
// specialized for TraitClass=char
}
};

I got it to compile with CBUilderX (has an EDG frontend) also.
I have done some digging and found a few blurbs in my google-mining
that says something to the effect that specialization of member
functions for a non-specialized class is not supported.

So I have 2 questions:

1. Has the standard changed and MS is on the ball, or is it a MS
compiler extension that allows this to work?

Nope, but its quite common for compilers to get this "cutting edge"
stuff wrong. Which is wrong though I don't know, though in my brief
scan of the standard I was unable to find anything excluding them.

Note that there is no way of defining these specialization's outside
the of the class template, so *if* legal they have to be "inline".
2. Would greatly appreciate suggestions on how to get around this
issue, I really really would like to have specialized member
functions.
The usual workaround is an extra level of indirection:

template < typename T > class TestClass; // forward

template < typename T >
struct SpecializedMember_helper
{
template < typename U >
static void apply( TestClass< U > &that )
{
//non specilaized functionality
}
};

template < >
struct SpecializedMember_helper< int >
{
template < typename U >
static void apply( TestClass< U > &that )
{
//int specilaized functionality
}
};


template < typename Traits >
class TestClass
{
//...
template < typename T >
void SpecializedMember_()
{
SpecializedMember_helper< T >::apply( *this );
}
};

This also works for partial specialization's.

If T always equals U in your real code (as it did in your example)
then SpecializedMember_helper<T>::apply() doesn't need to be a
template.

HTH.

Rob.
 
P

Patrick Kutch

Thanx to Rob and others for the assistance. When I move to a non-trivial
class, bad things still happen under Linux. Please take a look at the
following code:
-----------------------------------
// forward decl
template<class TraitClass1, class TraitClass2, bool TraitFlag> class
MyTestClass;

template<typename T>
struct Trait1SpecializedMember_Helper
{
static void Foo() // dummy funct that has to templ params
{
printf("General\n");
}

template <class MyTestClass > // passing inst of my class so I can call
back into it
static void apply(MyTestClass &that)
{
printf("General - Apply\n");
}
};
// my class
template <class TraitClass1 = int, class TraitClass2=char, bool
TraitFlag=false>
class MyTestClass
{
public:
void DoFuncTrait1()
{
Trait1SpecializedMember_Helper<TraitClass1>::Foo(); // works
great!
// get errors under Linx saying 'parse error before ';' token

Trait1SpecializedMember_Helper<TraitClass1>::apply<MyTestClass<TraitClass1,T
raitClass2,TraitFlag> >(*this);

// however this works!

Trait1SpecializedMember_Helper<int>::apply<MyTestClass<TraitClass1,TraitClas
s2,TraitFlag> >(*this);
}
};

------------------------------------

It would appear that I am unable to use template parameters for both the
creation of the struct AND paremeters to a function within that struct.

Meaning I can call: Trait1SpecializedMember_Helper<TraitClass1>::Foo();
Just fine and I can call:
Trait1SpecializedMember_Helper<int>::apply<MyTestClass<TraitClass1,TraitClas
s2,TraitFlag> >(*this); without any problems,

However when I try to call a function that uses template parametes for both
the struct specializaiton and the function call:
Trait1SpecializedMember_Helper<TraitClass1>::apply<MyTestClass<TraitClass1,T
raitClass2,TraitFlag> >(*this);

Some compilers do not like it. Which is find, if I could find a
work-around, for this work-around. :)

thanx,

Patrick
 
R

Rob Williscroft

Patrick Kutch wrote in
// get errors under Linx saying 'parse error before ';' token

Trait1SpecializedMember_Helper<TraitClass1>::apply<MyTestClass<TraitCla
ss1,T raitClass2,TraitFlag> >(*this);

Note the ::template below:

Trait1SpecializedMember_Helper<TraitClass1>
::template apply<
MyTestClass said:
;

Also since at the above point you're in the declaration of
MyTestClass<> you should be able to write:

Trait1SpecializedMember_Helper<TraitClass1>
::template apply< MyTestClass >(*this)
;

The ::template is required here as the specialization:

Trait1SpecializedMember_Helper< TraitClass1 >

depends on a template paramiter TraitClass1. The compiler needs to be
told that this specialization has a template member apply, otherwise
it assumes that apply is static data and interprets the following <
as the "less than" operator not the opening < of a template paramiter
list. I hope this explains why it worked for Foo() (not a template)
and for <int> (int isn't a dependant name).

Rob.
 
P

Patrick Kutch

Dude! That was it!

Thanx so much! I would have never been able to figure that out. I thought
I was coming up to speed pretty well with Template, but that kicked my butt.

Do you have any recomendations for some web sites or books so I can better
understand what you showed me?

thanx again!

- Patrick
 
R

Rob Williscroft

Patrick Kutch wrote in
Thanx so much! I would have never been able to figure that out. I
thought I was coming up to speed pretty well with Template, but that
kicked my butt.

Do you have any recomendations for some web sites or books so I can
better understand what you showed me?

You can pick up most of this stuff reading this group,
comp.lang.c++.moderated and comp.std.c++.

Lurking on boost's http://www.boost.org/ developer mailing list
can also be an education:

news://news.gmane.org/gmane.comp.lib.boost.devel.

I haven't got it myself but Andrei Alexandrescu's Modern C++ Design
http://www.moderncppdesign.com. Will probably teach you more than
you really wanted to know, his site contains a whole bunch of links
you might want to follow, including 2 chapters from his book.

Rob.
 
P

Patrick Kutch

Rob Williscroft said:
Patrick Kutch wrote in

You can pick up most of this stuff reading this group,
comp.lang.c++.moderated and comp.std.c++.

Lurking on boost's http://www.boost.org/ developer mailing list
can also be an education:

news://news.gmane.org/gmane.comp.lib.boost.devel.

I haven't got it myself but Andrei Alexandrescu's Modern C++ Design
http://www.moderncppdesign.com. Will probably teach you more than
you really wanted to know, his site contains a whole bunch of links
you might want to follow, including 2 chapters from his book.

Rob.

Thanx.

I am on boot's list. I have Andrei's book - kicked my arse! I loved it.
Still a lot over my head, but I am enjoying the challenge.

Thanx again!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,159
Messages
2,570,879
Members
47,417
Latest member
DarrenGaun

Latest Threads

Top