|
Boost Users : |
From: Ovanes Markarian (om_boost_at_[hidden])
Date: 2007-03-28 05:14:42
On Wed, March 28, 2007 02:57, Scott Meyers wrote:
> Given some base class,
>
> class Base { virtual ~Base(){} };
>
> I want to be able to implement this:
>
> template<typename Seq>
> const Base& createObject()
> {
> // return an object that inherits from Base and every type in Seq
> }
>
> The problem is how to create the type of object I want.
>
> mpl::inherit is almost what I need, but it takes as template parameters each
> type to inherit from, and I don't have discrete types, I have a sequence of
> types. mpl::inherit_linearly takes a sequence and would work for my purposes
> (which is to create an object that I can later check via dynamic_cast to see if
> it inherits from a given type), but it works only with forward sequences, and
> I'll typically have an mpl::set. I could copy the contents of Seq into an
> mpl::vector and go from there, but that seems kind of gross.
>
> Is there a good way to solve this problem that I am overlooking?
>
> Thanks,
>
> Scott
>
Scott,
I still think inherit_lineraly is what you need. mpl::set is also a Forward Sequence. The doc for
Forward Sequence states:
http://www.boost.org/libs/mpl/doc/refmanual/forward-sequence.html
A Forward Sequence is an MPL concept representing a compile-time sequence of elements. Sequence
elements are types, and are accessible through Iterators. The begin and end metafunctions provide
iterators delimiting the range of the sequence elements. A sequence guarantees that its elements
are arranged in a definite, but possibly unspecified, order. !!!Every MPL sequence is a Forward
Sequence.!!!
In the forward sequence docs is also defined:
For any Forward Sequence s the following expressions must be valid:
Expression Type Complexity
begin<s>::type Forward Iterator Amortized constant time
end<s>::type Forward Iterator Amortized constant time
size<s>::type Integral Constant Unspecified
empty<s>::type Boolean Integral Constant Constant time
front<s>::type Any type Amortized constant time
As I can see all these expressions are valid for mpl::set, so you can use inherit_linearly. The
only thing I would take care of, is to skip some fundamental types if these are possible in your
set (this can be done by using the combination of type_traits::is_scalar, mpl::filter_view,
mpl::inherit and mpl::inherit_linearly)
You can fine tune the is_scalar to identify type which can not be base...
Here the tested example with MSVC 8.0 Express Edition:
#include <boost/mpl/set.hpp>
#include <boost/mpl/filter_view.hpp>
#include <boost/mpl/inherit.hpp>
#include <boost/mpl/inherit_linearly.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/type_traits/is_scalar.hpp>
namespace bb = boost::bimap;
namespace mpl = boost::mpl;
struct A
{
int get()const
{
return a_;
}
int a_;
};
struct B
{
int get()const
{
return b_;
}
int b_;
};
struct C
{
double get()const
{
return c_;
}
double c_;
};
typedef mpl::set<A, B, bool, double, int(*)(), C> mixed_set;
typedef mpl::inherit_linearly
<
mpl::filter_view< mixed_set, mpl::not_< boost::is_scalar<mpl::_> > >
, mpl::inherit
<
mpl::_1
, mpl::_2
>
>::type inherited_type;
template<class T, class Res_>
Res_ call_get(T const& t)
{
return t.get();
}
int main()
{
inherited_type t;
call_get<A, int>(t);
call_get<C, double>(t);
return 0;
}
With Kind Regards,
Ovanes Markarian
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net