Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Template : class specialization

I'm new in the C++ world. Sorry for my nooby question.

I have a class

template <typename T>
class Foo
{
  T t_;
  void say_hello() 
  { std::cout << "Ciao";}
  // work with T ...
};

I want to specialize this template class for 3 types.

If type is (A or B or C), Then use this class

template<>
class Foo<A or B or C>
{
  void say_hello() 
  { std::cout << "Hello";}
};

What's the best way to do this? Thank you for your help.

like image 388
Andrew Avatar asked Mar 19 '26 23:03

Andrew


2 Answers

A possible solution uses SFINAE

template <typename T, typename = void>
class Foo
{
  T t_;
  void say_hello() 
  { std::cout << "Ciao";}
  // work with T ...
};

template <typename T>
class Foo<T, std::enable_if_t<std::is_same_v<T, A>,
                           || std::is_same_v<T, B>,
                           || std::is_same_v<T, C>>
{
  void say_hello() 
  { std::cout << "Hello";}
};

If you don't use T inside the Foo specialization (as in your example) you can also use a sort of self-inheritance

template <typename T>
class Foo
{
  T t_;
  void say_hello() 
  { std::cout << "Ciao";}
  // work with T ...
};

template <>
class Foo<A>
{
  void say_hello() 
  { std::cout << "Hello";}
};

template <>
class Foo<B> : public Foo<A>
 { };

template <>
class Foo<C> : public Foo<A>
 { };

Off Topic: if you want to use say_hello() outside the class, is better if you make it public (or if you declare Foo as a struct).

like image 196
max66 Avatar answered Mar 22 '26 14:03

max66


There are several possibilities, for example:

Specialization of the method only:

template<>
void Foo<A>::say_hello() { std::cout << "Hello"; }
template<>
void Foo<B>::say_hello() { std::cout << "Hello"; }
template<>
void Foo<C>::say_hello() { std::cout << "Hello"; }

or, in C++17, you might do:

template <typename T>
class Foo
{
  T t_;
  void say_hello() 
  {
      if constexpr(std::is_same_v<T, A> || std::is_same_v<T, B> || std::is_same_v<T, C>) {
          std::cout << "Hello";
      } else {
          std::cout << "Ciao";
      }
  }
  // work with T ...
};

Whereas regular if works in that example, it would fail if you call code specific to A, B, C. if constexpr won't have that issue.

like image 32
Jarod42 Avatar answered Mar 22 '26 14:03

Jarod42



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!