I've got problem with creating function that for given type, if it's derived from other one do something and for all other cases do something other. My code:
class BaseClass {};
class DerivedClass : public BaseClass {};
template <typename T>
void Function(typename std::enable_if<std::is_base_of<BaseClass, T>::value, T>::type && arg) {
std::cout << "Proper";
}
template <typename T>
void Function(T && arg) {
std::cout << "Improper";
}
void test() {
Function(DerivedClass{});
}
For class DeriviedClass
and other based on BaseClass
I'd like to call function couting Proper
, but it couts Improper
. Any suggestions?
It is possible to inherit from a template class. All the usual rules for inheritance and polymorphism apply. If we want the new, derived class to be generic it should also be a template class; and pass its template parameter along to the base class.
Difference between Base class and Derived class in C++ Base Class: A base class is a class in Object-Oriented Programming language, from which other classes are derived. The class which inherits the base class has all members of a base class as well as can also have some additional properties.
Defining a Function TemplateA function template starts with the keyword template followed by template parameter(s) inside <> which is followed by the function definition. In the above code, T is a template argument that accepts different data types ( int , float , etc.), and typename is a keyword.
" typename " is a keyword in the C++ programming language used when writing templates. It is used for specifying that a dependent name in a template definition or declaration is a type.
As mentioned in the comments to the question, SFINAE expressions won't work the way you did it.
It should be instead something like this:
template <typename T>
typename std::enable_if<std::is_base_of<BaseClass, T>::value>::type
Function(T && arg) {
std::cout << "Proper" << std::endl;
}
template <typename T>
typename std::enable_if<not std::is_base_of<BaseClass, T>::value>::type
Function(T && arg) {
std::cout << "Improper" << std::endl;
}
SFINAE expressions will enable or disable Function
depending on the fact that BaseClass
is base of T
. Return type is void
in both cases, for it's the default type for std::enable_it
if you don't define it.
See it on coliru.
Other valid alternatives exist and some of them have been mentioned in other answers.
#include <typeinfo>
#include <iostream>
class BaseClass {};
class DerivedClass : public BaseClass {};
class OtherClass {};
template <typename T,typename = typename std::enable_if<std::is_base_of<BaseClass, T>::value, T>::type>
void Function(T && arg)
{
std::cout << "Proper" << std::endl;
}
void Function(...)
{
std::cout << "Improper"<< std::endl;
}
int main()
{
Function(DerivedClass{});
Function(BaseClass{});
Function(OtherClass{});
}
template <typename T>
auto Function(T && arg) -> typename std::enable_if<std::is_base_of<BaseClass, T>::value>::type
{
std::cout << "Proper";
}
template <typename T>
auto Function(T && arg) -> typename std::enable_if<!std::is_base_of<BaseClass, T>::value>::type
{
std::cout << "Improper";
}
wandbox example
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With