Jump to content

  • Log In with Google      Sign In   
  • Create Account

FREE SOFTWARE GIVEAWAY

We have 4 x Pro Licences (valued at $59 each) for 2d modular animation software Spriter to give away in this Thursday's GDNet Direct email newsletter.


Read more in this forum topic or make sure you're signed up (from the right-hand sidebar on the homepage) and read Thursday's newsletter to get in the running!


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


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
8 replies to this topic

#1 zfvesoljc   Members   -  Reputation: 444

Like
0Likes
Like

Posted 23 November 2011 - 12:15 PM

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?

Sponsor:

#2 kilah   Members   -  Reputation: 513

Like
1Likes
Like

Posted 23 November 2011 - 12:32 PM

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.

#3 zfvesoljc   Members   -  Reputation: 444

Like
0Likes
Like

Posted 23 November 2011 - 01:50 PM

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?

#4 kilah   Members   -  Reputation: 513

Like
0Likes
Like

Posted 23 November 2011 - 04:46 PM

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.

#5 zfvesoljc   Members   -  Reputation: 444

Like
0Likes
Like

Posted 24 November 2011 - 01:05 AM

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;std::tr1::is_floating_point<T>::value == true if and only if T is one of the following types:

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

http://publib.boulde...type_traits.htm

#6 zfvesoljc   Members   -  Reputation: 444

Like
0Likes
Like

Posted 24 November 2011 - 01:36 AM

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

Any other ideas?

#7 IFooBar   Members   -  Reputation: 906

Like
1Likes
Like

Posted 24 November 2011 - 03:21 AM

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); }};


#8 patrrr   Members   -  Reputation: 1052

Like
0Likes
Like

Posted 24 November 2011 - 03:22 AM

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.

#9 zfvesoljc   Members   -  Reputation: 444

Like
0Likes
Like

Posted 24 November 2011 - 04:21 AM

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.




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS