Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c++ > #15467

Re: Generalizing Mixins... c++'03

From Werner <werasm@gmail.com>
Newsgroups comp.lang.c++
Subject Re: Generalizing Mixins... c++'03
Date 2012-04-19 01:04 -0700
Organization http://groups.google.com
Message-ID <32761594.292.1334822664654.JavaMail.geo-discussion-forums@vbus19> (permalink)
References <1918928.987.1334758911926.JavaMail.geo-discussion-forums@vbus19>

Show all headers | View raw


On Wednesday, April 18, 2012 4:21:51 PM UTC+2, Werner wrote:
> Hi All,
> 
> I've recently used mixins (without the courtesy of 
> compilers supporting variadic templates) and were 
> irritated by the fact that one had to always implement 
> many constructors (one per base):
> 
> Definition of Mixin: courtesy of http://www.drdobbs.com/cpp/184404445
> 
> A mixin is a fragment of a class that is intended to be composed with other classes or mixins...
> 
> For the problem I've come up with this solution (amongst others).
> 
> What do you think?
> 
> 
> //////////////////////////////////////
> #include <iostream>
>  
> struct Base
> {
>   Base();
>   Base( int i, int j ){}
>   virtual void foo()
>   {
>     std::cout << "Base::foo()" << std::endl;
>   }
> };
>  
> template <class BaseT>
> struct Mixin : virtual BaseT
> {
>   typedef BaseT base_type;
>   //Problem
>   //-Which constructor...? Always default... Generic!
>  
>   //Adds foo to any Base...
>   virtual void foo()
>   {
>     std::cout << "Derived::foo()" << std::endl;
>   }
> };
>  
> //Solution? Something that calls base 
> // constructor directly-always...
>  
> template <class MixinT>
> struct GenMixin : 
>   virtual MixinT::base_type,
>   MixinT
> {
>   typedef typename MixinT::base_type base_type;
>   GenMixin()
>   {
>   }
>   template <class A0>
>   GenMixin( A0 a0 )
>   : base_type( a0 )
>     //Mixin always has default only...
>   {
>   }
>   template <class A0, class A1>
>   GenMixin( A0 a0, A1 a1 )
>   : base_type( a0, a1 )
>     //Mixin always has default only...
>   {
>   }
> };
>  
> typedef GenMixin<Mixin<Base> > MyMixin;
> int main()
> {
>   MyMixin( 1, 2 ).foo();
> }

I know the solution above is ugly, but I found 
it an interesting exercise. It only works well
if the mixin has a default constructor. Using the
new standard this is what I've come up with (which
I suppose is the solution people use nowadays...).

Kind regards,

Werner

#include <iostream>
 
struct Base
{
  Base()
  {
    std::cout << "Base() called." << std::endl;
  }
  Base( int i, int j )
  {
    std::cout << "Base ( " << i << ", " << j << " ) called." << std::endl;
  }
  virtual void foo()
  {
    std::cout << "Base::foo()" << std::endl;
  }
};
 
template <class BaseT>
struct Mixin : virtual BaseT
{
  template <typename ...BaseArgs>
  Mixin( const char*, BaseArgs&&... args )
  : BaseT( std::forward<BaseArgs>(args)... )
  {
  }
  //Adds foo to any Base...
  virtual void foo()
  {
    std::cout << "Derived::foo()" << std::endl;
  }
};

typedef Mixin<Base> MyMixin;
int main()
{
  MyMixin( "Hallo", 10, 20 ).foo();
} 




Back to comp.lang.c++ | Previous | Next — Previous in thread | Find similar | Unroll thread


Thread

Generalizing Mixins... c++'03 Werner <werasm@gmail.com> - 2012-04-18 07:21 -0700
  Re: Generalizing Mixins... c++'03 Werner <werasm@gmail.com> - 2012-04-19 01:04 -0700

csiph-web