Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c++ > #15467
| 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> |
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
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