Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Template specialization for a group of types

Reply
Thread Tools

Template specialization for a group of types

 
 
Marc Schellens
Guest
Posts: n/a
 
      11-20-2003
I posted a similar question some time ago, but didn't get an
satisfying answer.

Lets say I have a template and five integer and two floating
types.

template <typename T> class A
{
A() {}
~A() {}

public:
void B( T);
};

// for all int
template <typename T> void B( T)
{
// do something with int (char, unsigned int ...)
}


template<> void B( float)
{
// do something with float
}
template<> void B( double)
{
// do something with double where the code looks the same as for float
}

How to avoid to replicate the code for float and double?
Or is it not possible?

Thanks,
marc

 
Reply With Quote
 
 
 
 
Patrick Kowalzick
Guest
Posts: n/a
 
      11-20-2003
Hi Marc,

I just wanted to post the same question .

What I do: I use macros for that purpose, but I do not like it . Please
see the code below:

So I would be happy to get a nicer solution as well.

Regards,
Patrick


// ***** CODE *****

struct A_1 {};
struct A_2 {};
struct B_1 {};
struct B_2 {};

// my class bar
template <typename> class bar;

// first GROUP of specializations of bar
#define create_class_A_bar(CA) \
template <> class bar<CA> \
{ \
typedef CA used_type; \
};

// class definitions Group A
create_class_A_bar(A_1);
create_class_A_bar(A_2);

// second GROUP of specializations of bar
#define create_class_B_bar(CB) \
template <> class bar<CB> \
{ \
typedef CB used_type; \
};

// class definitions Group A
create_class_B_bar(B_1);
create_class_B_bar(B_2);

// some usage
int main()
{
bar<A_1>;
bar<A_2>;
bar<B_1>;
bar<B_2>;

return 0;
}


 
Reply With Quote
 
 
 
 
tom_usenet
Guest
Posts: n/a
 
      11-20-2003
On Thu, 20 Nov 2003 14:25:22 +0900, Marc Schellens
<(E-Mail Removed)> wrote:

>I posted a similar question some time ago, but didn't get an
>satisfying answer.
>
>Lets say I have a template and five integer and two floating
>types.
>
>template <typename T> class A
>{
>A() {}
>~A() {}
>
>public:
>void B( T);
>};
>
>// for all int
>template <typename T> void B( T)
>{
>// do something with int (char, unsigned int ...)
>}
>
>
>template<> void B( float)
>{
>// do something with float
>}
>template<> void B( double)
>{
>// do something with double where the code looks the same as for float
>}
>
>How to avoid to replicate the code for float and double?
>Or is it not possible?


It is possible:

/* If you can't use boost
template <class T>
struct is_integral
{
static bool const value = false;
};

template<> struct is_integral<int>{static bool const value = true;};
template<> struct is_integral<unsigned>{static bool const value =
true;};
template<> struct is_integral<short>{static bool const value = true;};
template<> struct is_integral<unsigned short>{static bool const value
= true;};
template<> struct is_integral<char>{static bool const value = true;};
template<> struct is_integral<unsigned char>{static bool const value =
true;};
template<> struct is_integral<signed char>{static bool const value =
true;};
template<> struct is_integral<long>{static bool const value = true;};
template<> struct is_integral<unsigned long>{static bool const value =
true;};

//need const/volatile versions, etc. too!
//what about bool?
*/
// The boost version:
#include <boost/type_traits.hpp>
using boost::is_integral;

template <typename T> class A
{
public:
A() {}
~A() {}
void B(T);
};

#include <iostream>

template <bool B>
struct B_impl
{
template <class T>
static void impl(T t)
{
std::cout << "Integer version\n";
}
};
template <>
struct B_impl<false>
{
template <class T>
static void impl(T t)
{
std::cout << "Float version\n";
}
};
// for all int
template <typename T> void A<T>::B(T t)
{
B_impl<is_integral<T>::value>::impl(t);
}

int main()
{
A<short> a;
a.B(5);

A<double> b;
b.B(7.5);
}

Tom
 
Reply With Quote
 
Rob Williscroft
Guest
Posts: n/a
 
      11-20-2003
Marc Schellens wrote in news:(E-Mail Removed):

> I posted a similar question some time ago, but didn't get an
> satisfying answer.
>
> Lets say I have a template and five integer and two floating
> types.
>
> template <typename T> class A
> {
> A() {}
> ~A() {}
>
> public:
> void B( T);
> };
>
> // for all int
> template <typename T> void B( T)
> {
> // do something with int (char, unsigned int ...)
> }
>
>
> template<> void B( float)
> {
> // do something with float
> }
> template<> void B( double)
> {
> // do something with double where the code looks the same as for float
> }
>
> How to avoid to replicate the code for float and double?
> Or is it not possible?
>


An alternative is a simple refactor:

template < typename T> A< T >::B( T arg )
{
// int version.
}

/* New (?private?) member
template < typename T> A< T >::B_float( T arg )
{
// int version.
}

template <> inline A< float >::B( float arg )
{
B_float( arg );
}

template <> inline A< double >::B( double arg )
{
B_float( arg );
}

If you like typing (or you *need* to generalize),

#include <iostream>
#include <ostream>
#include <limits>

#if 0 /* boost is preferable if you have it */
#include "boost/mpl/if.hpp"
using boost::mpl::if_c;
#else
template < bool True, typename TrueT, typename FalseT >
struct if_c
{
typedef TrueT type;
};
template < typename TrueT, typename FalseT >
struct if_c< false, TrueT, FalseT >
{
typedef FalseT type;
};
#endif

template < typename T, typename Arg, void (T::*F)( Arg ) >
struct member_ref_1
{
static void apply( T *that, Arg arg )
{
(that->*F)( arg );
}
};


template < typename T > struct A
{
void B_int( T arg ) { std::cerr << "int\n"; }
void B_float( T arg ) { std::cerr << "float\n"; }

void B( T arg )
{
typedef
if_c<
std::numeric_limits< T >::is_integer,
member_ref_1< A< T >, T, &A< T >::B_int >,
member_ref_1< A< T >, T, &A< T >::B_float >
>

::type type
;
type::apply( this, arg );
}
};

int main()
{
A< int > aint;
aint.B( 0 );

A< double > adouble;
adouble.B( 0.0 );
}

Rob.
--
http://www.victim-prime.dsl.pipex.com/
 
Reply With Quote
 
Chris Theis
Guest
Posts: n/a
 
      11-24-2003

"Patrick Kowalzick" <(E-Mail Removed)> wrote in message
news:bphujb$ri3$(E-Mail Removed)...
> Hi Marc,
>
> I just wanted to post the same question .
>
> What I do: I use macros for that purpose, but I do not like it . Please
> see the code below:
>
> So I would be happy to get a nicer solution as well.
>
> Regards,
> Patrick
>
>
> // ***** CODE *****
>
> struct A_1 {};
> struct A_2 {};
> struct B_1 {};
> struct B_2 {};
>
> // my class bar
> template <typename> class bar;
>
> // first GROUP of specializations of bar
> #define create_class_A_bar(CA) \
> template <> class bar<CA> \
> { \
> typedef CA used_type; \
> };
>
> // class definitions Group A
> create_class_A_bar(A_1);
> create_class_A_bar(A_2);
>
> // second GROUP of specializations of bar
> #define create_class_B_bar(CB) \
> template <> class bar<CB> \
> { \
> typedef CB used_type; \
> };
>
> // class definitions Group A
> create_class_B_bar(B_1);
> create_class_B_bar(B_2);
>
> // some usage
> int main()
> {
> bar<A_1>;
> bar<A_2>;
> bar<B_1>;
> bar<B_2>;
>
> return 0;
> }



One possible solution would be the usage of type lists although, as
discussed with Patrick, IMHO would be simply too much overhead for such a
problem. The standard stream library has the same problem to cope with
(overloading of op << for all the different POD types) and there you see
that it's done "by hand". In lack of better ideas I'd personally stick with
the macros. Sure, the statement "macros are evil" is more or less true but
there are exceptions.

Regards
Chris


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Template specialization for a list of types mschellens C++ 9 03-27-2013 12:16 PM
template specialization with function types question Tom C++ 0 03-31-2010 05:58 AM
Trying to use templated types as parameters in template specialization. David O C++ 2 01-10-2007 02:53 PM
template specialization overriding non-specialization? Joseph Turian C++ 2 04-16-2006 02:46 PM
Specialization of a template within template David B. Held C++ 2 10-26-2003 11:59 AM



Advertisments