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;
}
Specializations for two types
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.
Yes, like so:
Does this help?
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.
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.)
I also added in methods foo() and bar() to show how some methods can be specialized while others are common to all instantiations.
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
Popular Topics
Advertisement