Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

template specialization for all subclasses

I would like to define a C++ template specialization that applies to all subclasses of a given base class. Is this possible?

In particular, I'd like to do this for STL's hash<>. hash<> is defined as an empty parametrized template, and a family of specializations for specific types:

template<class _Key>
  struct hash { };

template<>
  struct hash<char>
  {
    size_t
    operator()(char __x) const
    { return __x; }
  };

template<>
  struct hash<int>
  {
    size_t
    operator()(int __x) const
    { return __x; }
  };
...

I would like to define something like this:

template<class Base>
  struct hash {
    size_t operator()(const Base& b) const {
      return b.my_hash();
    }
  };

class Sub : public Base {
  public:
    size_t my_hash() const { ... }
};

and be able to use it like this:

hash_multiset<Sub> set_of_sub;
set_of_sub.insert(sub);

However, my hash template conflicts with the generic one from STL. Is there a way (perhaps using traits) to define a template specialization that applies to all subclasses of a given base class (without modifying the STL definitions)?

Note that I know I can do this with some extra template parameters whenever this hash specialization is needed, but I'd like to avoid this if possible:

template<>
  struct hash<Base> {
    size_t operator()(const Base& b) const {
      return b.my_hash();
    }
  };

....

// similar specialization of equal_to is needed here... I'm glossing over that...
hash_multiset<Sub, hash<Base>, equal_to<Base> > set_of_sub;
set_of_sub.insert(sub);
like image 896
Warren Harris Avatar asked Oct 01 '11 17:10

Warren Harris


People also ask

What is template specialization?

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.

What is the difference between partial specialization and template specialization?

Templates can have more than one parameter type. Some older compilers allow one only to specialize either all or none of the template's parameters. Compilers that support partial specialization allow the programmer to specialize some parameters while leaving the others generic.

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.

How many types of template are there in C++?

Technical overview. 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.


1 Answers

Since C++ 11 you can use SFINAE together with standard library enable_if and is_base_of to solve the problem.

like image 76
Zig Razor Avatar answered Oct 19 '22 00:10

Zig Razor