Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c++ > #15453 > unrolled thread
| Started by | Werner <werasm@gmail.com> |
|---|---|
| First post | 2012-04-18 07:21 -0700 |
| Last post | 2012-04-19 01:04 -0700 |
| Articles | 2 — 1 participant |
Back to article view | Back to comp.lang.c++
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
| From | Werner <werasm@gmail.com> |
|---|---|
| Date | 2012-04-18 07:21 -0700 |
| Subject | Generalizing 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]
| From | Werner <werasm@gmail.com> |
|---|---|
| Date | 2012-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