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


Groups > comp.lang.c++ > #15453 > unrolled thread

Generalizing Mixins... c++'03

Started byWerner <werasm@gmail.com>
First post2012-04-18 07:21 -0700
Last post2012-04-19 01:04 -0700
Articles 2 — 1 participant

Back to article view | Back to comp.lang.c++


Contents

  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

#15453 — Generalizing Mixins... c++'03

FromWerner <werasm@gmail.com>
Date2012-04-18 07:21 -0700
SubjectGeneralizing Mixins... c++'03
Message-ID<1918928.987.1334758911926.JavaMail.geo-discussion-forums@vbus19>
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();
}

[toc] | [next] | [standalone]


#15467

FromWerner <werasm@gmail.com>
Date2012-04-19 01:04 -0700
Message-ID<32761594.292.1334822664654.JavaMail.geo-discussion-forums@vbus19>
In reply to#15453
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();
} 




[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.c++


csiph-web