c++ - Eliminate redundancy with CRTP and multiple inheritance -


this question c++03, not c++11.

i have case using crtp multiple inheritance, , curious know if there way remove redundancy created when specifying type of b below.

#include "boost/typeof/typeof.hpp" #include "boost/units/detail/utility.hpp" #include <iostream> #include <string>  struct one{}; struct two{};  template<typename t> struct type {    static std::string name(void)    {       return boost::units::detail::demangle(typeid(t).name());    } };  template<typename t1,          typename t2> struct {    typedef a<t1, t2> self;     a()    {       std::cout << type<self>::name() << std::endl;    } };  template<typename t1,          typename t2,          typename t3> struct b : public a<one, b<t1, t2, t3> >, // b<t1, t2, t3> here redundant            public a<two, b<t1, t2, t3> > {    typedef b<t1, t2, t3> self;     b()    {       std::cout << type<self>::name() << std::endl;    } };  int main(int argc, char* argv[]) {    b<int, int, int> t;    return 0; } 

see on coliru

the problem worsens when number of template parameters b increases, when template arguments complex, , when b inherits a more times. i'd minimize repetition of b's template parameters. specifically, looking way access typedef b<t1, t2, t3> self in inheritance list b, or equivalent compile-time version of this.

i cannot:

  • make typedef b above b using forward declaration, because don't have access template parameters
  • make typedef inside of inheritance definition because syntax doesn't allow that
  • access typedef inside class, because doesn't exist yet

something below (none of not valid code, display effect looking for):

template<typename t1,          typename t2,          typename t3> struct b : public a<one, self>, // cannot access typedef yet            public a<two, self> {    typedef b<t1, t2, t3> self; };  template<typename t1,          typename t2,          typename t3> struct b : typedef b<t1, t2, t3> self, // invalid syntax            public a<one, self>,             public a<two, self> {  };  template<typename t1,          typename t2,          typename t3> struct b : public a<one, b>, // wish work            public a<two, b> {  };  template<typename t1,          typename t2,          typename t3> struct b : public a<one, boost_typeof(*this)>, // lol            public a<two, boost_typeof(*this)> {  }; 

is there way access compile-time version of this?

the problem with:

template<typename t1,          typename t2,          typename t3> struct b : public a<one, b>, // wish work            public a<two, b> {  }; 

is template <typename t1, typename t2> struct a asks instantiated t2 type, whereas wish instantiate t2 template, namely template<typename, typename,typename> struct b.

if definition of a lies in own control, perhaps - though perhaps not - solution make definition of a consistent wish:

#include "boost/typeof/typeof.hpp" #include "boost/units/detail/utility.hpp" #include <iostream> #include <string>  struct one{}; struct two{};  template<typename t> struct type {    static std::string name(void)    {       return boost::units::detail::demangle(typeid(t).name());    } };  template<typename t1,          template<typename, typename, typename> class t2 > struct {     a()    {       std::cout << type<a>::name() << std::endl;    } };   template<typename t1,          typename t2,          typename t3> struct b : public a<one, b >,            public a<two, b > {    b()    {       std::cout << type<b>::name() << std::endl;    } };   int main(int argc, char* argv[]) {    b<int, int, int> t;    return 0; } 

this program prints:

a<one, b> a<two, b> b<int, int, int> 

the price of solution restricting classes a can furnish crtp base ones instantiate template, b, of 3 typename parameters.

perhaps lucky enough restriction not thwart other wishes have. if need a furnish crtp base classes instantiate template not have 3 typename parameters, bites.

provided of classes need a furnish crtp base instantiations of templates have typename parameters, , have @ n of them, can still have c++03 solution in same spirit:

you define a per schema:

template<typename t1,          template<typename /*1*/,.... typename /*n*/> class t2 > struct { ... }; 

and each template y a crtp base, provide n parameters, employing "padding" parameters default void, necessary. example, if n == 3:

#include "boost/typeof/typeof.hpp" #include "boost/units/detail/utility.hpp" #include <iostream> #include <string>  struct one{}; struct two{};  template<typename t> struct type {    static std::string name(void)    {       return boost::units::detail::demangle(typeid(t).name());    } };  template<typename t1,          template<typename, typename, typename> class t2 > struct {     a()    {       std::cout << type<a>::name() << std::endl;    } };   template<typename t1, typename t2 = void, typename t3 = void> struct b : public a<one, b >,            public a<two, b > {    b()    {       std::cout << type<b>::name() << std::endl;    } };  template<typename t1, typename t2, typename t3 = void> struct c : public a<one, c >,            public a<two, c > {    c()    {       std::cout << type<c>::name() << std::endl;    } };  template<typename t1, typename t2, typename t3> struct d : public a<one, d >,            public a<two, d > {    d()    {       std::cout << type<d>::name() << std::endl;    } };    int main(int argc, char* argv[]) {    b<int> b;    c<int,int> c;    d<int,int,int> d;    return 0; } 

this program prints:

a<one, b> a<two, b> b<int, void, void> a<one, c> a<two, c> c<int, int, void> a<one, d> a<two, d> d<int, int, int> 

true, more general solution sticks different kind of "redundancy", in form of superfluous defaulted template parameters. may find less irksome kind.

(gcc 5.1/clang 3.6, c++03)


Comments

Popular posts from this blog

powershell Start-Process exit code -1073741502 when used with Credential from a windows service environment -

twig - Using Twigbridge in a Laravel 5.1 Package -

c# - LINQ join Entities from HashSet's, Join vs Dictionary vs HashSet performance -