3

In Java generic, when I want to ensure that the type of some generic class must inherit a class, I can code as below:

public class MyHandler<T extends Serializable> {}

This means that T must extend/implement the class/interface Serializable, otherwise, the compiler will generate an error.

How to get the same thing in C++11? I mean, if I code C++11 as below:

template<typename T>
class MyHandler {}

In this piece of code, T can be any class. But, if I want to tell the class users that T must inherit the class boost::archive::text_oarchive (just like <T extends Serializable> in Java), what can I do?

Milan
  • 1,743
  • 2
  • 13
  • 36
Yves
  • 11,597
  • 17
  • 83
  • 180
  • Do you want to prevent instantiating objects from your class at compile-time or run-time? – asmmo Jul 21 '20 at 03:36
  • @asmmo Usually the point of this is to prevent failed instantiations due to an incompatible type argument from producing incomprehensible errors. As such, and since templates are a compile-time thing anyway, preventing it at run-time makes no sense whatsoever -- you cannot instantiate a template at run-time. – cdhowie Jul 21 '20 at 03:37
  • @cdhowie I know that but I would prefer `std::enable_if` to the posted answer, hence I asked that question. or Have I missed a thing? – asmmo Jul 21 '20 at 03:42
  • @asmmo Both `std::enable_if` and the technique in the posted answer are 100% compile-time. – cdhowie Jul 21 '20 at 05:31

1 Answers1

4

You can use std::is_base_of for checking.

template<typename T>
class MyHandler {
    static_assert(std::is_base_of<boost::archive::text_oarchive, T>::value, "T must inherit boost::archive::text_oarchive");
};

Since C++20 we can use constraint, e.g.

template<typename T> requires std::is_base_of_v<boost::archive::text_oarchive, T>
class MyHandler {};
songyuanyao
  • 169,198
  • 16
  • 310
  • 405