Connecting Tech Pros Worldwide Forums | Help | Site Map

Specialization of Member functions

Patrick Kutch
Guest
 
Posts: n/a
#1: Jul 22 '05
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!



Slawomir Lisznianski
Guest
 
Posts: n/a
#2: Jul 22 '05

re: Specialization of Member functions


Patrick Kutch wrote:[color=blue]
> 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!
>[/color]

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


Sharad Kala
Guest
 
Posts: n/a
#3: Jul 22 '05

re: Specialization of Member functions



"Patrick Kutch" <Patrick@dsl-only.net> wrote in message
news:400dfe10$1@nntp0.pdx.net...[color=blue]
> 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?[/color]

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

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



Patrick Kutch
Guest
 
Posts: n/a
#4: Jul 22 '05

re: Specialization of Member functions



"Slawomir Lisznianski" <slisznianski@asyncnet.com> wrote in message
news:b5udnXWlLZoRYJDdRVn-jA@dls.net...[color=blue]
> Patrick Kutch wrote:[color=green]
> > 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[/color][/color]
with[color=blue][color=green]
> > 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[/color][/color]
a[color=blue][color=green]
> > 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[/color][/color]
compiler[color=blue][color=green]
> > extension that allows this to work?
> >
> > 2. Would greatly appreciate suggestions on how to get around this[/color][/color]
issue, I[color=blue][color=green]
> > really really would like to have specialized member functions.
> >
> > thanx!
> >[/color]
>
> 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
>
>[/color]
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


Rob Williscroft
Guest
 
Posts: n/a
#5: Jul 22 '05

re: Specialization of Member functions


Patrick Kutch wrote in news:400dfe10$1@nntp0.pdx.net:
[color=blue]
> Please take a look at the following code snippit:
> -------------------------------------------------------
> template<class TraitClass=int>
> class TestClass
> {
> public:
> void CallFunc()
> {[/color]

This is suspect, why wre you passing in the current template's
paramiter, members are already "specialized" on this paramiter.
[color=blue]
> 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.
>[/color]

I got it to compile with CBUilderX (has an EDG frontend) also.
[color=blue]
> 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?
>[/color]

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".
[color=blue]
> 2. Would greatly appreciate suggestions on how to get around this
> issue, I really really would like to have specialized member
> functions.
>[/color]
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.
--
http://www.victim-prime.dsl.pipex.com/
Patrick Kutch
Guest
 
Posts: n/a
#6: Jul 22 '05

re: Specialization of Member functions


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<MyTestC lass<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<MyTestC lass<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


Rob Williscroft
Guest
 
Posts: n/a
#7: Jul 22 '05

re: Specialization of Member functions


Patrick Kutch wrote in news:40118329$1@nntp0.pdx.net:
[color=blue]
> // get errors under Linx saying 'parse error before ';' token
>
> Trait1SpecializedMember_Helper<TraitClass1>::apply <MyTestClass<TraitCla
> ss1,T raitClass2,TraitFlag> >(*this);
>
>[/color]

Note the ::template below:

Trait1SpecializedMember_Helper<TraitClass1>
::template apply<
MyTestClass<TraitClass1,T raitClass2,TraitFlag>[color=blue]
>(*this)[/color]
;

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.
--
http://www.victim-prime.dsl.pipex.com/
Patrick Kutch
Guest
 
Posts: n/a
#8: Jul 22 '05

re: Specialization of Member functions


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

"Rob Williscroft" <rtw@freenet.REMOVE.co.uk> wrote in message
news:Xns9479D428510D4ukcoREMOVEfreenetrtw@195.129. 110.205...[color=blue]
> Patrick Kutch wrote in news:40118329$1@nntp0.pdx.net:
>[color=green]
> > // get errors under Linx saying 'parse error before ';' token
> >
> > Trait1SpecializedMember_Helper<TraitClass1>::apply <MyTestClass<TraitCla
> > ss1,T raitClass2,TraitFlag> >(*this);
> >
> >[/color]
>
> Note the ::template below:
>
> Trait1SpecializedMember_Helper<TraitClass1>
> ::template apply<
> MyTestClass<TraitClass1,T raitClass2,TraitFlag>[color=green]
> >(*this)[/color]
> ;
>
> 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.
> --
> http://www.victim-prime.dsl.pipex.com/[/color]


Rob Williscroft
Guest
 
Posts: n/a
#9: Jul 22 '05

re: Specialization of Member functions


Patrick Kutch wrote in news:40119e10$1@nntp0.pdx.net:
[color=blue]
>
> 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?
>[/color]

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.
--
http://www.victim-prime.dsl.pipex.com/
Patrick Kutch
Guest
 
Posts: n/a
#10: Jul 22 '05

re: Specialization of Member functions



"Rob Williscroft" <rtw@freenet.REMOVE.co.uk> wrote in message
news:Xns947A9806D258ukcoREMOVEfreenetrtw@195.129.1 10.201...[color=blue]
> Patrick Kutch wrote in news:40119e10$1@nntp0.pdx.net:
>[color=green]
> >
> > 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?
> >[/color]
>
> 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.
> --
> http://www.victim-prime.dsl.pipex.com/[/color]

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!


Closed Thread