Jump to content
  • Advertisement
Sign in to follow this  
ndwork

Specializations for two types

This topic is 3451 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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

Share this post


Link to post
Share on other sites
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 here
class 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?

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!