[mpl] Inheriting from each type in a sequence
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
On 3/27/07, Scott Meyers
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.
Thanks,
Scott
I'm probably won't use the correct mpl-isms, but something like
template <typename Seq>
struct inherit_all
{
struct type
:
public virtual first<Seq>::type,
public virtual inherit_all
template<typename Seq> const Base& createObject() { // return an object that inherits from Base and every type in Seq return new Base_and_Seq<Seq>(); }
Does any of that work, or at least head in the right direction? Or am I just recreating what inherit_linearly, etc already does? Tony
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?
An Associative Sequence is a Forward Sequence, so 'inherit_linearly< a_set, inherit<_1,_2> >::type' works. Regards, Tobias
Tobias Schwinger wrote:
An Associative Sequence is a Forward Sequence, so 'inherit_linearly< a_set, inherit<_1,_2> >::type' works.
Ah, thanks. The MPL Reference manual does not list set as a model of a Forward Sequence, nor does it list Associative Sequence as a model, so I foolishly assumed that a set probably violated the "two iterations through the container must see the elements in the same order" requirement. Next time I'll have to read more closely. Scott
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
participants (4)
-
Gottlob Frege
-
Ovanes Markarian
-
Scott Meyers
-
Tobias Schwinger