 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Mark Van Peteghem Guest
|
Posted: Thu Apr 21, 2005 2:29 am Post subject: Partial specialization of template method |
|
|
I'm trying to do partial specialization on a template method of a
(non-template) class, but I keep getting compile errors. Am I doing
this the wrong way, or is it impossible?
I use MingW32, version 3.4.2.
class MyClass
{
public:
template<typename T1, typename T2>
void foo();
};
template<typename T1, typename T2>
void MyClass::foo()
{
std::cout << "in foo" << std::endl;
}
// full specialization of foo is fine
template<>
void MyClass::foo<float,float>()
{
std::cout << "in specialization of foo" << std::endl;
}
// next part gives compile errors
template
void MyClass::foo<int, T2>()
{
std::cout << "in partial specialization of foo" << std::endl;
}
--
Mark dot Van dot Peteghem at q-mentum dot com
http://www.q-mentum.com -- easier and more powerful unit testing
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
CrayzeeWulf Guest
|
Posted: Thu Apr 21, 2005 8:45 am Post subject: Re: Partial specialization of template method |
|
|
Mark Van Peteghem wrote:
| Quote: | I'm trying to do partial specialization on a template method of a
(non-template) class, but I keep getting compile errors. Am I doing
this the wrong way, or is it impossible?
|
Function templates cannot have partial specializations:
http://www.gotw.ca/publications/mill17.htm
--
CrayzeeWulf
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Mark Van Peteghem Guest
|
Posted: Thu Apr 21, 2005 1:45 pm Post subject: Re: Partial specialization of template method |
|
|
CrayzeeWulf wrote:
| Quote: | Mark Van Peteghem wrote:
I'm trying to do partial specialization on a template method of a
(non-template) class, but I keep getting compile errors. Am I doing
this the wrong way, or is it impossible?
Function templates cannot have partial specializations:
http://www.gotw.ca/publications/mill17.htm
Thank you for this link. It is a disappointment to read that it can't |
be done, just because the standard says so.
The solution that Herb Sutter proposes is elegant, but alas it can't
be used for template member functions: a static method of a nested
class can't access the members of the class. Does anyone have an idea
of the 'next best thing' to solve what I try to do?
--
Mark dot Van dot Peteghem at q-mentum dot com
http://www.q-mentum.com -- easier and more powerful unit testing
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Daniel Krügler (ne Spange Guest
|
Posted: Thu Apr 21, 2005 4:50 pm Post subject: Re: Partial specialization of template method |
|
|
Hello Mark,
Mark Van Peteghem schrieb:
| Quote: | CrayzeeWulf wrote:
Mark Van Peteghem wrote:
I'm trying to do partial specialization on a template method of a
(non-template) class, but I keep getting compile errors. Am I doing
this the wrong way, or is it impossible?
Function templates cannot have partial specializations:
http://www.gotw.ca/publications/mill17.htm
Thank you for this link. It is a disappointment to read that it can't
be done, just because the standard says so.
The solution that Herb Sutter proposes is elegant, but alas it can't
be used for template member functions: a static method of a nested
class can't access the members of the class. Does anyone have an idea
of the 'next best thing' to solve what I try to do?
It should work. Try the following approach: |
class MyClass
{
private:
template<typename T1, typename T2>
class FooEvaluator {
public:
static void call(MyClass&);
};
void some_private_membar();
void some_private_memfoo();
void some_private_memadvanced();
public:
template<typename T1, typename T2>
void foo() {
FooEvaluator<T1, T2>::call(*this);
}
};
// General def:
template<typename T1, typename T2>
void MyClass::FooEvaluator<T1, T2>::call(MyClass& arg)
{
arg.some_private_membar();
}
// full specialization:
template<>
void MyClass::FooEvaluator<float,float>::call(MyClass& arg)
{
arg.some_private_memfoo();
}
// partial spec:
template<typename T2>
class MyClass::FooEvaluator<int, T2> {
public:
static void call(MyClass& arg) {
arg.some_private_memadvanced();
}
};
void test() {
MyClass c;
c.foo<double, unsigned>(); // calls general
c.foo<float, float>(); // calls full spec.
c.foo<int, double>(); // calls partial spec.
}
Greetings from Bremen,
Daniel Krügler
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Tom Widmer Guest
|
Posted: Fri Apr 22, 2005 11:51 am Post subject: Re: Partial specialization of template method |
|
|
Mark Van Peteghem wrote:
| Quote: | CrayzeeWulf wrote:
Mark Van Peteghem wrote:
I'm trying to do partial specialization on a template method of a
(non-template) class, but I keep getting compile errors. Am I doing
this the wrong way, or is it impossible?
Function templates cannot have partial specializations:
http://www.gotw.ca/publications/mill17.htm
The solution that Herb Sutter proposes is elegant, but alas it can't
be used for template member functions: a static method of a nested
class can't access the members of the class. Does anyone have an idea
of the 'next best thing' to solve what I try to do?
|
Sure such a static member can - just pass the this pointer to the
function. e.g.
class C
{
template <class T>
struct f_impl
{
static void f(C* p, T t);
}
public:
template <class T>
void f(T t)
{
f_impl<T>::f(this, t);
}
};
//partially specialize f_impl as necessary,
//but make sure specializations are declared before any instantiations
of f.
f_impl obviously doesn't need to be a nested class if you don't want it
to be. You can make it a friend if it needs private/protected access.
Tom
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Mark Van Peteghem Guest
|
Posted: Sat Apr 23, 2005 2:06 am Post subject: Re: Partial specialization of template method |
|
|
Daniel Krügler (ne Spangenberg) wrote:
| Quote: | It should work. Try the following approach:
class MyClass
{
private:
template<typename T1, typename T2
class FooEvaluator {
public:
static void call(MyClass&);
};
void some_private_membar();
void some_private_memfoo();
void some_private_memadvanced();
public:
template
void foo() {
FooEvaluator
}
};
// General def:
template<typename T1, typename T2
void MyClass::FooEvaluator
{
arg.some_private_membar();
}
// full specialization:
template
void MyClass::FooEvaluator<float,float>::call(MyClass& arg)
{
arg.some_private_memfoo();
}
// partial spec:
template<typename T2
class MyClass::FooEvaluator
public:
static void call(MyClass& arg) {
arg.some_private_memadvanced();
}
};
void test() {
MyClass c;
c.foo<double, unsigned>(); // calls general
c.foo<float, float>(); // calls full spec.
c.foo<int, double>(); // calls partial spec.
}
|
That's a neat solution, but I need a solution where I can add partial
specializations that the class doesn't need to know about. With your
solution this can't be done, because it requires a method that the
class knows off.
Maybe a solution with a non-member function is possible, but that
also doesn't work in my situation, I need a member function.
--
Mark dot Van dot Peteghem at q-mentum dot com
http://www.q-mentum.com -- easier and more powerful unit testing
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Graeme Prentice Guest
|
Posted: Wed Apr 27, 2005 8:15 am Post subject: Re: Partial specialization of template method |
|
|
On 22 Apr 2005 22:06:01 -0400, Mark Van Peteghem wrote:
| Quote: | Daniel Krügler (ne Spangenberg) wrote:
It should work. Try the following approach:
|
[snip]
| Quote: |
That's a neat solution, but I need a solution where I can add partial
specializations that the class doesn't need to know about. With your
solution this can't be done, because it requires a method that the
class knows off.
Maybe a solution with a non-member function is possible, but that
also doesn't work in my situation, I need a member function.
|
Can you declare a nested template class in the original class?
If so, you can partially specialize the nested class without the
original class knowing (as shown in 14.5.4/6)
template<class T> struct A {
class C {
template<class T2> struct B { };
};
};
// partial specialization of A<T>::C::B<T2>
template<class T> template<class T2>
struct A<T>::C::B<T2*> { };
I don't have time to think about the details right now but you may be
able to hand off the function call to a member function of the partial
specialization similarly to what Herb does. However you'll need to make
sure the specializations are declared before they're referenced. If you
have problems making the nested class and its specializations friends of
the parent class, you may need to re-hand off the call to a non-member
class ... If it ends up working, it might be fragile.
See also this http://makeashorterlink.com/?E3D6526FA
for the SFINAE version of member function partial specialization. You
could use boost enable_if instead of what I do there.
Graeme
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
|
|
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
|
|