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 

live

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();     }     ... }; 

live2


Comments

Popular posts from this blog

sequelize.js - Sequelize group by with association includes id -

android - Robolectric "INTERNET permission is required" -

java - Android raising EPERM (Operation not permitted) when attempting to send UDP packet after network connection -