Reputation: 1447
I know a little knowledge about C++ 11 template. My intention is to have a template function as shown below:
template<class T>
void function(T * a) {
if (T belongs to class M) {
a->function_m();
} else {
a->function_o();
}
}
Does C++ 11 support this template class reflection?
Upvotes: 4
Views: 1641
Reputation: 648
What u want can be done in c++17
template <typename T>
void function( T* a )
{
if constexpr (std::is_base_of<M,T>::value)
a->function_m();
else
a->function_o();
}
Full example : http://melpon.org/wandbox/permlink/MsHnYQNlBcRhTu2C As referred by @Fabio Fracassi
Upvotes: 0
Reputation: 3249
Yes, and better yet, you don't need to perform if(...){} else{}
statements to do so. You can use tag dispatching or specializations to avoid the conditional statements. The following example uses tag dispatching.
Example:
#include <iostream>
#include <type_traits>
template <typename B, typename D>
void function( D* a )
{
function( a, typename std::is_base_of<B, D>::type{} );
}
template <typename T>
void function( T* a, std::true_type )
{
a->function_b();
}
template <typename T>
void function( T* a, std::false_type )
{
a->function_c();
}
struct B
{
virtual void function_b() { std::cout << "base class.\n"; }
};
struct D : public B
{
void function_b() override { std::cout << "derived class.\n"; }
};
struct C
{
void function_c() { std::cout << "some other class.\n"; }
};
int main()
{
D d;
C c;
function<B, D>( &d );
function<B, C>( &c );
}
This mechanism does not require both functions to be visible in the same scope.
Upvotes: 5
Reputation: 217970
Several choices:
SFINAE:
template<class T>
std::enable_if_t<std::is_base_of<M, T>>
function(T* a)
{
a->function_m();
}
template<class T>
std::enable_if_t<!std::is_base_of<M, T>>
function(T* a)
{
a->function_o();
}
or tag dispatching:
namespace details {
template<class T>
void function(T* a, std::true_type) {
a->function_m();
}
template<class T>
void function(T* a, std::false_type) {
a->function_o();
}
}
template<class T>
void function(T* a)
{
details::function(a, std::is_base_of<M, T>{});
}
Upvotes: 3
Reputation: 64308
Yes, std::is_base_of<Base,Derived>
:
template<class T>
void function(T * a) {
if (std::is_base_of<M,T>::value) {
a->function_m();
} else {
a->function_o();
}
}
However, it is likely to cause a problem in this case, since function_m()
and function_o()
would both need to be callable.
Upvotes: 1