Voko
Voko

Reputation: 778

C++ inherit template specializations

I have a template function that does something depending on the type passed as a template argument:

template<class T>
void foo() {
  if constexpr (std::is_integral_v<T>) {
    //  ...
  } else if constexpr ... {
    // ...
  }
}

The problem with this it that I don't really need to have a function instantiation for every possible integral type (to avoid template code bloat), so I would like to have only one instance that takes a int and if we pass the type char or short it calls the int version. I would like something like this:

template<class T>
void foo() {
  if constexpr (std::is_same_v<T, int>) { // Only check for `int`, because "lower" types will be converted to int
    //  ...
  } else if constexpr ... {
    // ...
  }
}

foo<short>(); // Call `foo<int>`
foo<char>(); // Call `foo<int>`
foo<int>(); // Call `foo<int>`

Maybe I can wrap the function inside a struct and have a struct<char> that extends the struct<int>?

Note that there is no "values" anywhere, I just have template parameters.

Upvotes: 0

Views: 80

Answers (1)

康桓瑋
康桓瑋

Reputation: 42776

You can turn foo into a callable object, and use using alias to select different instantiations according to T, for example:

#include <type_traits>

template<class T>
struct foo {
 void operator()() {
    if constexpr (std::is_same_v<T, int>) {
      //  ...
    } else if constexpr ... {
      // ...
    }
 }
};

template<class T>
auto bar = std::conditional_t<std::is_integral_v<T>, foo<int>, foo<T>>();

int main() {
  bar<short>(); // Call `foo<int>`
  bar<char>();  // Call `foo<int>`
  bar<int>();   // Call `foo<int>`
  bar<const char*>(); // Call `foo<const char*>`
}

Upvotes: 2

Related Questions