Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c++ template specialization for base class

I would like to have a special formatter for BASECLASS and all derived classes. I have the following classes:

struct BASECLASS { ... };
struct SPECIALFORMAT : BASECLASS { ... }
struct ANOTHERSPECIALFORMAT : BASECLASS { ... }

template <class T>
struct LISTFORMATTER {
  list<T> l;

  bool format() {

  };
}
bool LISTFORMATTER<BASECLASS>::format() { ... }

LISTFORMATTER<BASECLASS> bcFt;
LISTFORMATTER<SPECIALFORMAT> spFt;
LISTFORMATTER<ANOTHERSPECIALFORMAT> aspFt;

bcFt.format(); // <-- ok
spFt.format(); // <-- Calling standard format(), not specialized
aspFt.format(); // <-- Calling standard format(), not specialized

How can I specialize a method for a base class and all inherited classes?

EDIT preferible not using boost. c++ (not c++11)

like image 833
Miquel Avatar asked Jan 29 '14 17:01

Miquel


1 Answers

First, you need is_base_of. If you don't want to use Boost or C++11, then grab one here: How does `is_base_of` work?

Then, you can do this:

template <bool B> struct bool_ {};
// ...
bool format() { do_format(bool_<is_base_of<BASECLASS, T>::value>()); }
bool do_format(bool_<false>) {
  // not inheriting BASECLASS
}
bool do_format(bool_<true>) {
  // inheriting BASECLASS
}

BTW, there is, AFAIK, no way of doing this non-intrusively, i.e. simply by adding a specialization.

Edit: Actually, you can probably do it without is_base_of:

// ...
bool format() { do_format((T*)0); }
bool do_format(void*) { /* not inheriting */ }
bool do_format(BASECLASS*) { /* inheriting */ }

This works because derived->base is a better conversion than class->void.

like image 51
Sebastian Redl Avatar answered Sep 19 '22 04:09

Sebastian Redl