Partial template specialization for a method

P

__PPS__

Hello,
I want to write specialized method for a class:

template<class A, class B>
class xxx{
A a; B b;
operator bool()const{
a==b;
}
};

What I want to do is to be able to specialize operator bool for the
case when class A=std::string, so that in that case it returned
a.length()>0;

For this to work I have a choice to copy my class xxx definition like
this:

template<class B>
class xxx<std::string, B>{
std::string a; B b;
operator bool()const{
a.length()>0;
}
};

But I have a large class where I need to specialize several methods.
What I want to do is to specialize only the method operator bool:

template<class A, class B>
class xxx{
A a; B b;
operator bool()const;
};

//default implementation
template<class A, class B>
xxx<A,B>::eek:perator bool()const{
return a==b;
}

//specialized method, doesn't compile
template<class B>
xxx<std::string, B>::eek:perator bool()const{
return a.length()>0;
}

but it doesn't work like this. What's the mistake, how to do it the
right way?
I use vs2003

Thank you.
 
V

Victor Bazarov

__PPS__ said:
Hello,
I want to write specialized method for a class:

template<class A, class B>
class xxx{
A a; B b;
operator bool()const{
a==b;
}
};
[...]

There are no partial specialisations of function templates.

You may be able to work around that limitation by using overloading.

V
 
B

block111

I meant explicit specialization of a method in case if the first
template argument is an std::string
Have no idea how overloading can help in this case (I think it would be
useless overhead in terms of lines of code and it wouldn't prevent me
from using default operator bool if I one day forgot about overloaded
class for std::string) but if ther's no way to do that, then the best
way is do it the way I described in my post (to copy class
declaration...), but whenever I want to modify class I also need to
update all copies of it... seems like there must be a better way to do
what I want...
 
B

block111

I fond a workaround:

template<class A, class B>
class xxx{
template<class C>bool op_bool()const{ /* default implementation */ }
template<>bool op_bool<std::string>()const{ /* std::string case */ }
A a; B b;
public:
operator bool()const{ return op_bool<A>(); }
};
 
V

Victor Bazarov

I fond a workaround:

template<class A, class B>
class xxx{
template<class C>bool op_bool()const{ /* default implementation */ }
template<>bool op_bool<std::string>()const{ /* std::string case */ }
A a; B b;
public:
operator bool()const{ return op_bool<A>(); }
};

Not legal IIRC. Specialisations shall not be defined inside the class.
 
B

block111

I found the same argument why it was disallowed in g++ - using g++33
and g++34 I cannot compile this code, however it works with vs2003 and
vc++ 8. As far as I'm concerned it also works with intel compiler.
(http://lists.debian.org/debian-gcc/2004/09/msg00015.html)

trying to move the line
template<>bool op_bool<std::string>()const{ /* std::string case */ }
outside class definition brought even worse problem than what I
originally started this thread with.

If suppose you are correct on that case, then what sort of cryptic code
I need to write to put this specialization outside the class body? At
least I don't see any reason for the standard to force to put this sort
of specialization outside the class body...

ms compiler help: "C++ member templates are supported as long as they
are fully defined within the enclosing class...."
meaning that I cannot even put implementation of a templated method of
a templated class outside of the body of the class with ms compier.


According to the link about g++, there's a way to make it work - define
inner struct with unused template parameter and do a partial
specialization instead of full specialization... seems to be a really
ugly solution for my original problem...


template<typename T, typename _unused>
struct _bool{ inline bool operator()(const T& v)const{ return
v!=T();} };
template<typename _unused>
struct _bool<std::string,_unused>{ inline bool operator()(const
std::string&v)const{ return v.length()>0;}};

operator bool(){ return _bool<A,void>(a); }

works with g++ also, but is really ugly IMO
 

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
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top