Generalizing Mixins... c++'03

W

Werner

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();
}
 
W

Werner

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();
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top