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

Started by
7 comments, last by zfvesoljc 12 years, 5 months ago
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?
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.

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?
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.

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]

  • [const] [volatile] float
  • [const] [volatile] double
  • [const] [volatile] long double

[font="Arial, sans-serif"] [/font]
http://publib.boulde...type_traits.htm
Ran into a problem, the type_traits is not implemented on the target platform...

Any other ideas?

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); }};
[size=2]aliak.net
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.

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.

This topic is closed to new replies.

Advertisement