c++ - How can I deal with undesired template instantiation for a function that isn't called? -


i'm trying implementing code want call templated methods based on type traits. unfortunately, methods instantiated types (that never called said types) incompatible function, causes compilation errors. ideally use traits prevent said uncalled methods being instantiated that's not case, i'm looking workaround or design pattern can use.

i have few simple pod structs. each type has different members (their existence indicated corresponding traits)

struct thinga {     int a; };  struct thingab {     int a;     int b; };  struct thingabc {     int a;     int b;     int c; };  template <typename thing> struct thingtraits {     static const bool has_a=false;     static const bool has_b=false;     static const bool has_c=false; }; 

here's template function; thinga, thingab , thingabc can passed either src or dst type

template<typename src, typename dst> void assign(src const &src, dst &dst) {     constexpr bool c_a = thingtraits<src>::has_a && thingtraits<dst>::has_a;     constexpr bool c_b = thingtraits<src>::has_b && thingtraits<dst>::has_b;     constexpr bool c_c = thingtraits<src>::has_c && thingtraits<dst>::has_c;      c_a ? copy_a(src,dst) : do_nothing();     c_b ? copy_b(src,dst) : do_nothing();     c_c ? copy_c(src,dst) : do_nothing(); } 

the copy_a/b/c methods copy corresponding member:

template<typename src, typename dst> void copy_a(src const &src, dst &dst) {     dst.a = src.a; }  template<typename src, typename dst> void copy_b(src const &src, dst &dst) {     dst.b = src.b; }  template<typename src, typename dst> void copy_c(src const &src, dst &dst) {     dst.c = src.c; } 

when trying compile this, errors because copy_a/b/c instantiated types required members don't exist (ie copy_b).

how can implement functionally equivalent since way doesn't work? need thinga,ab,abc stay simple pods no additional members (size req strict) , don't want determine copy operations call during run time.

you may have like:

template<bool hasa> struct copy_a_caller {     template <typename src, typename dst>     void operator () (const src& src, dst& dst) const     {         dst.a = src.a;     } };  template<> struct copy_a_caller<false> {     template <typename src, typename dst>     void operator () (const src&, dst&) const {} };  template<typename src, typename dst> void copy_a(src const &src, dst &dst) {     copy_a_caller<thingtraits<src>::has_a && thingtraits<dst>::has_a>()(src, dst); }  // similar thing b , c 

and then

template<typename src, typename dst> void assign(src const &src, dst &dst) {     copy_a(src, dst);     copy_b(src, dst);     copy_c(src, dst); } 

Comments

Popular posts from this blog

c++ - OpenMP unpredictable overhead -

ruby on rails - RuntimeError: Circular dependency detected while autoloading constant - ActiveAdmin.register Role -

javascript - Wordpress slider, not displayed 100% width -