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'; }