|
Prev: Defect Report: integral_constat::value should be constexpr
Next: please get me learn c++ web . 3Q 3Q~~
From: miconnor on 19 Jun 2008 11:27 Is it possible to declare a template specialization in c++ that fits multiple classes? For example, I have a class that needs a specialization for 4 different "types" of type. I need one specialization for unsigned integer types (long, short, int), one for signed integer types, one for signed floating point types (float, double), and one for unsigned. Can I get away with only 4 template specializations? Or do I need to duplicate the code for every type? -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Oncaphillis on 20 Jun 2008 04:28 miconnor(a)gmail.com wrote: > Can I get away with only 4 template specializations? Or do I need to > duplicate the code for every type? > You might want to factor out the decision about 'signedness' and 'fixedness' into two different template helper structs like this: <snip> template<class _N> struct is_signed { static const bool value=true; }; template<> struct is_signed<unsigned short> { static const bool value=false; }; template<> struct is_signed<unsigned long> { static const bool value=false; }; template<> struct is_signed<unsigned long long>{ static const bool value=false; }; template<> struct is_signed<unsigned int>{ static const bool value=false; }; template<class _N> struct is_fixed { static const bool value=true; }; template<> struct is_fixed<float>{ static const bool value=false; }; template<> struct is_fixed<double>{ static const bool value=false; }; </snip> After this you can declare and specialize your template class as follows <snip> template<class _N, bool _IS_FIXED=is_fixed<_N>::value, bool _IS_SIGNED=is_signed<_N>::value > class do_something; template<class _N > class do_something<_N, true, true> { ... }; template<class _N > class do_something<_N, false, true> { ... }; int main() { // This will instantiate do_something<float,false,true> do_something<float> d; } </snip> Note that within this approach char is assumed to be signed and that at least on my platform there is no concept of a unsigned (float|double). HTH O. -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Greg Herlihy on 20 Jun 2008 04:40 On Jun 19, 7:27 pm, micon...(a)gmail.com wrote: > Is it possible to declare a template specialization in c++ that fits > multiple classes? Yes, by using type_traits to group related template type parameters. > For example, I have a class that needs a specialization for 4 > different "types" of type. I need one specialization for > unsigned integer types (long, short, int), one for signed integer > types, one for signed floating point types (float, double), and one > for unsigned. > > Can I get away with only 4 template specializations? Or do I need to > duplicate the code for every type? No, there are several ways that one could consolidate related types. For example, the program could declare four base classes (Integer, UnsignedInteger, Float, and UnsignedFloat) and then have the class template derive from the appropriate base class depending on the type of its template parameter: #include <tr1/type_traits> // or <boost/type_traits> // Declare four base classes to represent each of // the four number types struct Integer {}; struct UnsignedInteger {}; struct Float {}; struct UnsignedFloat {}; // does not exist in C++ // Declare a NumberTypeHelper class template that selects // one of the above classes - depending on the properties // of the arithmetic type provided template < bool IsArithmetic, // compile-time error, if false bool isIntegral, bool isSigned> struct NumberTypeHelper; // Note: declared, not defined // Specialize NumberTypeHelper for the each of the four supported // integral/float and signed/unsigned combinations template <> struct NumberTypeHelper<true, true, true> { typedef Integer type; }; template <> struct NumberTypeHelper<true, true, false> { typedef UnsignedInteger type; }; template <> struct NumberTypeHelper<true, false, true> { typedef Float type; }; template <> struct NumberTypeHelper<true, false, false> { typedef UnsignedFloat type; }; // Now have the Number class template use the NumberTypeHelper helper // class template to select the appropriate base class for the // template type parameter provided. using std::tr1::is_arithmetic; using std::tr1::is_integral; using std::tr1::is_signed; template <class T> struct Number : public NumberTypeHelper< is_arithmetic<T>::value, is_integral<T>::value, is_signed<T>::value >::type { // ... }; int main() { } Greg -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Phil Bouchard on 20 Jun 2008 04:30 <miconnor(a)gmail.com> wrote in message news:a961c9e4-b615-482e-a364-bfd519fd0c21(a)27g2000hsf.googlegroups.com... > Is it possible to declare a template specialization in c++ that fits > multiple classes? > > For example, I have a class that needs a specialization for 4 > different "types" of type. I need one specialization for > unsigned integer types (long, short, int), one for signed integer > types, one for signed floating point types (float, double), and one > for unsigned. > > Can I get away with only 4 template specializations? Or do I need to > duplicate the code for every type? Yeah it's called "partial template specialization": template <typename T> class A; template <typename T> class A<signed T> { ... }; template <typename T> class A<unsigned T> { ... }; -Phil -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: wasti.redl on 20 Jun 2008 04:42 On Jun 20, 4:27 am, micon...(a)gmail.com wrote: > For example, I have a class that needs a specialization for 4 > different "types" of type. I need one specialization for > unsigned integer types (long, short, int), one for signed integer > types, one for signed floating point types (float, double), and one > for unsigned. > > Can I get away with only 4 template specializations? Or do I need to > duplicate the code for every type? Yes, the enable_if utility (in TR1 or Boost) allows you to define a specialization that matches all types that fit some metaprogrammed criteria. In your case, such a criterium could be the type trait is_float, one could be a combination of is_integral and is_unsigned and the third is_integral and the negation of is_unsigned. There are no unsigned floating point types, though. -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
|
Next
|
Last
Pages: 1 2 Prev: Defect Report: integral_constat::value should be constexpr Next: please get me learn c++ web . 3Q 3Q~~ |