Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ Template Specialization and Subclassing

I was wondering if it is possible to have a template specialization accept a class and its subclasses. Like so:

class A {};

class B : public A {};

template <typename T>
void foo(const T& t) {
  printf("T");
}

template <>
void foo(const A& t) {
  printf("A");
}

int main(int argc, char** argv) {
  B b;
  foo(b);

  return 0;
}

Currently it output 'T' because b doesn't have its own template specialization, so it defaults to printing 'T'. I was wondering if it was possible for B to use the template specialization of A since B is a subclass of A. Or is that just not a thing?

Note: Because of some requirement, I can't use copy/move.

Note: I would also prefer if I didn't need to change A or B, but lets see what is possible first.

like image 424
Jack Blue Avatar asked May 13 '19 00:05

Jack Blue


People also ask

What is the difference between generic class template and specialization template?

Key differences between generics and C++ templates: Generics are generic until the types are substituted for them at runtime. Templates are specialized at compile time so they are not still parameterized types at runtime. The common language runtime specifically supports generics in MSIL.

What are the two types of templates in C++?

There are three kinds of templates: function templates, class templates and, since C++14, variable templates. Since C++11, templates may be either variadic or non-variadic; in earlier versions of C++ they are always non-variadic.

What is meant by template specialization in C++?

The act of creating a new definition of a function, class, or member of a class from a template declaration and one or more template arguments is called template instantiation. The definition created from a template instantiation is called a specialization.

Is class template and function template the same?

The difference is, that the compiler does type checking before template expansion. The idea is simple, source code contains only function/class, but compiled code may contain multiple copies of the same function/class. Function Templates We write a generic function that can be used for different data types.


1 Answers

The probelm is, the primary template is an exact match when T being deduced as B; it's a better match than the specialization.

You can use template overloading instead; with SFINAE.

template <typename T>
std::enable_if_t<!std::is_base_of_v<A, T>> foo(const T& t) {
  printf("T");
}

template <typename T>
std::enable_if_t<std::is_base_of_v<A, T>> foo(const T& t) {
  printf("A");
}

LIVE

like image 86
songyuanyao Avatar answered Oct 18 '22 20:10

songyuanyao