Tell me, is there a mechanism in C ++ for defining a template for which the user can specify only a limited number of classes — classes that are inherited from a particular class, i.e. something like

template<class object [implemented] base_class> func() {} class x: public base_class {}; class y {}; func<x>(); // все ок func<y>(); // ошибка 

    3 answers 3

    For example:

     class base_class { }; template< typename object, typename = enable_if_t<is_base_of_v<base_class,object>> > void func() {} class x: public base_class {}; class y {}; int main() { func<x>(); func<y>(); } 

    Look, there are many different properties that can be checked.

    • Harry, and the short built-in command in C + + did not appear? It looks cool, of course, but really scary :) - Zhihar
    • I have not heard :) In principle, everyone wants a language, but they will not introduce concepts at all (see, for example, this book ), but to say that they will be much shorter - I don’t think ... - Harry
    • @Zhihar You want to see the concepts. They will appear only in C ++ 20. en.cppreference.com/w/cpp/language/… - Chorkov

    Such tricks are usually abbreviated as SFINAE . They have been known since time immemorial, but since C ++ 11 many tools for this have appeared in the language and STL.

    For example:

     template<class T> std::enable_if_t<std::is_base_of_v<base_class, T>> func(); // enable_if_t is a using-alias for enable_if::type // which is only defined in case condition is true // and is void by default 

    By slightly changing the type of function, you can do without enable_if:

     #include <iostream> #include <utility> struct Base {}; template<typename T> decltype(static_cast<Base const &>(std::declval<T>()), int{}) omg (T &&) { return 42; } int omg(...) { return 314; } struct T: Base {}; struct U {}; int main() { std::cout << omg(T{}) << '\n'; std::cout << omg(U{}) << '\n'; } 
       template<class object> func() { static_assert(std::is_base_of_v<base_class, object>, "sorry :("); } 

      Only this, as they say, is not SFINAE-friendly, so the function overload will not work.