c++ - Make template function to destinguish inheritors and others -
i have class (base
) has many inheritors (derived_i
) , other types (other
). want have template method in class-handler (caller
), handles inheritors of base
in differ way, other types.
here example code telling about.
#include <iostream> using namespace std; template <typename t> class base { public: base (t val = t()) : m_val(val) {} base (const base &other) : base(other.m_val) {} virtual void base_specific_method() { cout << __func__ << " method called: " << m_val << endl; } void each_class_has_this() { cout << __func__ << " boring..." << endl; } t m_val; }; class other { public: void each_class_has_this() { cout << __func__ <<" boring..." << endl; } }; class derived_i : public base <int> { public: derived_i () : base <int> (10) {} virtual void base_specific_method() { cout << __func__ <<" hey! i'm interesting derived! , 10 == " << m_val << endl; } }; template <typename t> class caller { public: caller (t val = t()) : m_val(val) {} void call() { p_call(m_val); } private: template <typename t1> void p_call (t1 &val) { val.each_class_has_this(); } template <typename t1> void p_call (base<t1> &val) { val.base_specific_method(); } private: t m_val; }; int main () { caller<other> c1; caller<base<double> > c2; caller<derived_i > c3; c1.call(); c2.call(); c3.call(); }
it compiled g++ -std=c++11 test.cpp
, output next:
each_class_has_this boring... base_specific_method method called: 0 each_class_has_this boring...
while i'm expecting
each_class_has_this boring... base_specific_method method called: 0 base_specific_method hey! i'm interesting derived! , 10 == 10
is there way change code make suitable requests?
this question seems duplicate of another question, correct answer on leads problem, faced here.
p.s. there no way make base
, other
inheritors 1 class. =(
you can use std::enable_if
std::is_base_of
distinguish class derived base<t>
or not.
template <typename t, typename tt = void> class caller { public: caller (t val = t()) : m_val(val) {} void call() { p_call(m_val); } private: template <typename t1> typename std::enable_if<!std::is_base_of<base<tt>, t1>::value>::type p_call (t1 &val) { val.each_class_has_this(); } template <typename t1> typename std::enable_if<std::is_base_of<base<tt>, t1>::value>::type p_call(t1& val) { val.base_specific_method(); } private: t m_val; };
note base
template class, means t1
might derived class of base<int>
, or base<double>
, , on. can't count possibilities, template parameter tt
need specified hint. use as:
caller<other> c1; caller<base<double>, double> c2; caller<derived_i, int> c3; // derived_i derived base<int> c1.call(); c2.call(); c3.call();
result:
each_class_has_this boring... base_specific_method method called: 0 base_specific_method hey! i'm interesting derived! , 10 == 10
or can make base class make simple:
class abstract_base { public: virtual void base_specific_method() = 0; virtual ~abstract_base() {} }; template <typename t> class base : public abstract_base { ... }; ... template <typename t> class caller { ... template <typename t1> typename std::enable_if<!std::is_base_of<abstract_base, t1>::value>::type p_call (t1 &val) { val.each_class_has_this(); } template <typename t1> typename std::enable_if<std::is_base_of<abstract_base, t1>::value>::type p_call(t1& val) { val.base_specific_method(); } ... };
Comments
Post a Comment