• Advertisement
Sign in to follow this  

[c++] template magic (template class with member function specialization)

This topic is 2251 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

i'm trying to do create a template class and implement a specialized member function:

template<class T, class U>
class TFoobar {
public:
void func(T t, U u) { // generic }
void func(float t, U u); { // float spec }
}



I tried a few things, but didn't manage to make it work (or compile properly for both msvc and gcc). Can I make this work like outlined in the above snippet, or must I make a class specialization?

Share this post


Link to post
Share on other sites
Advertisement
What you are looking for is partial specialization, not all compilers support it, but it is incresingly common on most used ones. Also you must understand that T may be float, so you would endup with 2 definitions of a single method (forbidden). Therefore in order to avoid that problem, check type_traits which will allow you to "use one or the other based on type of class T".

Cheers.

Share this post


Link to post
Share on other sites

What you are looking for is partial specialization, not all compilers support it, but it is incresingly common on most used ones. Also you must understand that T may be float, so you would endup with 2 definitions of a single method (forbidden).


yep, found that out



Therefore in order to avoid that problem, check type_traits which will allow you to "use one or the other based on type of class T".
Cheers.


so basically I just branch the code based on the is_floating_point(), or any other that is?

Share this post


Link to post
Share on other sites
There are several ways to use enable_if/disable_if in this case, but my way of solving this would be a disable_if on your first func when is_floating returns true for T. This could lead you to another problem: What about double types? You would end up with only func(float.... ), not the generic one, which may, or may not, be a problem for you in this case.

Share this post


Link to post
Share on other sites

There are several ways to use enable_if/disable_if in this case, but my way of solving this would be a disable_if on your first func when is_floating returns true for T. This could lead you to another problem: What about double types? You would end up with only func(float.... ), not the generic one, which may, or may not, be a problem for you in this case.


quote:

is_floating_point
template <class _T> struct is_floating_point;[font="Arial, sans-serif"]std::tr1::is_floating_point<T>::value == true if and only if T is one of the following types:[/font]

Share this post


Link to post
Share on other sites

Ran into a problem, the type_traits is not implemented on the target platform...

Any other ideas?


Problem is you can't partially specialize functions, but you can partially specialize an implementation structure within TFoobar to get what you need

template<class T, class U>
class TFoobar {
public:
template <class T, class U>
struct func_impl {
static void impl(T t, U u) { }
};

template <class U>
struct func_impl<float, U> {
static void impl(float t, U u) { }
};

void func(T t, U u) { func_impl<T, U>::impl(t, u); }};

Share this post


Link to post
Share on other sites
How about...


template<typename T, typename U>
class Hi {
public:
void print(T) {
std::cout << "generic" << std::endl;
}
};

template<typename U>
class Hi<float, U> {
public:
void print(float) {
std::cout << "float" << std::endl;
}
};


?
If the class is big enough that this causes a lot of duplicated code, maybe you can pull this functionality out into another class or function and use that one from the "main" class.

Share this post


Link to post
Share on other sites

How about...


template<typename T, typename U>
class Hi {
public:
void print(T) {
std::cout << "generic" << std::endl;
}
};

template<typename U>
class Hi<float, U> {
public:
void print(float) {
std::cout << "float" << std::endl;
}
};


?
If the class is big enough that this causes a lot of duplicated code, maybe you can pull this functionality out into another class or function and use that one from the "main" class.




yeah, that was the initial solution (and currently implemented), but I'll try the method IFooBar provided.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement