I have a set of classes that have the following structure:
class U
{
public:
explicit U(int) { ... }
U() {...}
Init(int) {...}
};
I need to be able to compose 1 or more of these classes into a class X. Pseudocode:
template<class TypeSequence>
class X that derives publicly from all the classes in TypeSequence
{
X(int): all bases are initialized with the integer passed
{}
//if the above constructor is impossible, then the following will do as well:
X(int)
{
Call Init on all bases and pass the given int to them.
}
};
I think I need a lot of mpl, but I'm not really good at it. Is what am I trying to do doable? A code sample would be great.
MY FAULT: Forgot to mention I can't use C++11 features. I am looking for an MPL solution.
Well, Boost.MPL contains metafunctions inherit
and inherit_linearly
you can combine them with for_each
to get the second variant (with init functions). Or using just boost::mpl::fold
and custom metafunctions:
struct Null_IntConstructor
{
Null_IntConstructor(int) { }
};
struct InheritFrom_IntConstructor_Folder
{
template<typename T1, typename T2>
struct apply
{
struct type : T1, T2
{
type(int x) : T1(x), T2(x) { }
};
};
};
template<typename Bases>
struct InheritFrom_IntConstructor
: boost::mpl::fold<Bases,
Null_IntConstructor,
InheritFrom_IntConstructor_Folder>::type
{
InheritFrom_IntConstructor(int x)
: boost::mpl::fold<Bases,
Null_IntConstructor,
InheritFrom_IntConstructor_Folder>::type(x)
{ }
};
Usage example:
#include <iostream>
#include <boost/mpl/fold.hpp>
#include <boost/mpl/vector.hpp>
struct A
{
A(int x) { std::cout << "A::A " << x << std::endl; }
};
struct B
{
B(int x) { std::cout << "B::B " << x << std::endl; }
};
struct C
{
C(int x) { std::cout << "C::C " << x << std::endl; }
};
int main()
{
InheritFrom_IntConstructor< boost::mpl::vector<A, B, C> >(1);
}
Metafunction InheritFrom_IntConstructor
can generalized to accept arbitrary type as constructor parameter and I'm not sure if can generalized to accept arbitrary number of arguments.
Something like this?
template <typename ...BaseClasses>
class Aggregator : public BaseClasses...
{
public:
Aggregator(int i) : BaseClasses(i)...
{}
};
Usage example:
Aggregator<U, V, W> a(10);
Aggregator<U, V> b(15);
Aggregator<W> c(20);
Note: it uses variadic templates, so C++11 is required.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With