Specializations for two types

Started by
2 comments, last by visitor 15 years, 3 months ago
I am attempting to specialize a class for two different types. Is this possible? The code below doesn't compile because of the int|double statement.

template<class S, class T>
class A{
private:
  S a;
  T b;
public:
  A(){ std::cout << "Basic A" << std::endl; }
};

template<int|double, class T>
class A{
private:
  T b;
public:
  A(){ std::cout << "Specialized A" << std::endl;
};

int main( int argc, const char* argv[] ){
  A<char,char> charA;
  A<int,char> intA;
  A<double,char> dblA;
  std::cout << "program ended" << endl;
}

Advertisement
Yes, like so:

template<class S, class T>class A{private:  S a;  T b;public:  A(){ std::cout << "Basic A" << std::endl; }};template<class T> // notice only one parameter hereclass A<int,T> // specialization of A<S, T>, S=int{private:  int a;  // must include original members  T b;public:  A(){ std::cout << "Specialized A" << std::endl;};template<class T>class A<double,T> // specialization of A<S, T>, S=double{private:  double a;  T b;public:  A(){ std::cout << "Specialized A" << std::endl;};


Does this help?
It doesn't work becuase "int|double" doesn't name a type. Remember that templates are not pattern matching, they are type matching. (plus of course there are non type template arguments.)

Maybe you are going to write a "IntDouble" composite class, but I doubt that would be sane, so _fastcall is right. If you don't want to specialise whole classes, there's also the way to write template member functions (which is perfectly valid inside class templates). I do this very frequently.
It should also be possible without duplicating complicated specializations.

For example like this. There is a simple struct that is specialized for int and double and turns the choice between T, int and double into a choice between true and false. Also, all the functionality of A is inherited from BaseA, so that the need for the additional template argument (int_or_double<S>) is hidden from the user of A.

(If you need to specialize for more cases, e.g all integer and floating point types, then you could check out boost::type_traits, so you wouldn't have to write a huge number of tiny specializations yourself.)

#include <iostream>template <class X>struct int_or_double{  static const bool value = false;};template <>struct int_or_double<int>{  static const bool value = true;};template <>struct int_or_double<double>{  static const bool value = true;};template<bool, class S, class T>class BaseA{private:  S a;  T b;public:  BaseA(){ std::cout << "Basic A" << std::endl; }  void foo() { std::cout << "Basic foo()\n"; }};template<class S, class T>class BaseA<true, S, T>{private:  S a;  T b;public:  BaseA(){ std::cout << "Specialized A" << std::endl; }  void foo() { std::cout << "Special foo()\n"; }};template <class S, class T>class A: public BaseA<int_or_double<S>::value, S, T>{public:  void bar() { std::cout << "Shared bar()\n"; }};int main( int argc, const char* argv[] ){  A<char,char> charA;  charA.foo();  charA.bar();  A<int,char> intA;  intA.foo();  intA.bar();  A<double,char> dblA;  dblA.foo();  dblA.bar();  std::cout << "program ended" << std::endl;}


I also added in methods foo() and bar() to show how some methods can be specialized while others are common to all instantiations.

This topic is closed to new replies.

Advertisement