1

I have the following code that uses specialization to declare a typedef name type depending on the value of the non-template parameter value. As you can see below, the program works as expected but I would like to avoid code duplication that is shown in the comments of the program. In particular, I want that I don't have to repeat the 3 member function declarations or any other code except the typedef.   

template<bool value> struct S
{
    typedef int type;

     //a lot of code(declaraions, definitions etc) here for example
     type size();
     void func();
     int bar(int);
};

//specialization
template<> struct S<false>
{
     typedef unsigned type;
     //I WANT TO AVOID THIS REPETATION
     type size();
     void func();
     type bar(type);  
};


How can I achieve this for the code shown above. Note that the above is a minimal reproducible example that I created which has only one specialization as the template parameter is of type bool(which can have only true or false) but in practical example, the template parameter can be of some other type in which case(as you could imagine) it would become very tedious to repeat the code with the number of specialization.

Jason
  • 36,170
  • 5
  • 26
  • 60
Val
  • 148
  • 8

2 Answers2

2

You can move type aliases to base class and specialize based on template parameters

template<bool value>
struct Base {
  typedef int type;
};

template<>
struct Base<false> {
  typedef unsigned type;
};

template<bool value> 
struct S : Base<value>
{
  using type = Base<value>::type;
  // a lot of code(declaraions, definitions etc) here for example
  type size();
  void func();
  int bar(int);
};

Or more simply, use std::conditional_t

template<bool value> 
struct S
{
  using type = std::conditional_t<value, int, unsigned>;
  // a lot of code(declaraions, definitions etc) here for example
  type size();
  void func();
  int bar(int);
};
康桓瑋
  • 33,481
  • 5
  • 40
  • 90
2

You can use lambda and constexpr if to have all the code place at one place and avoid code duplication as shown below.

template<bool value> struct S
{
    using type = decltype([]()
                  {
                  if constexpr(value)
                  {
                        return int();
                  } 
                  else
                  {
                    return unsigned();
                  }
                  }()
                  ); 

     //a lot of code(declaraions, definitions etc) here for example
     type size();
     void func();
     int bar(int); 
};

int main()
{
    S<false>::type t1{};  //t1 is unsigned 
    S<true>::type t2{};   //t2 is int
}

Demo


Method 2

Alternatively, you can make the code even more compact(&readable) by using std::conditional to avoid decltype as shown below:

template<bool value> struct S
{
    using type = std::conditional_t<value, int, unsigned>;

     //a lot of code here for example
     type size();
     void func();
     int bar(int); 
};
Jason
  • 36,170
  • 5
  • 26
  • 60