
Scott Meyers wrote:
Daniel Wallin wrote:
This is unnecessarily inefficient. It's pretty easy to just use iterators, something like:
template <class First, class Last, class F> bool do_until_impl(First, Last, F f) { boost::value_initialized<typename mpl::deref<First>::type> x;
Does this not require that mpl::deref<First>::type be default-constructable? Presumably this is the first type in my type sequence, and since I'm dynamic_casting to all types in the sequence, it's not unreasonable to assume that the type I'm casting to may be abstract. Will this work if my sequence consists of abstract types? And even if the type is concrete, I can't, in general, know anything about constructing it, i.e., I can't know if it can be value-constructed.
I'm certainly not an MPL expert, but as far as I understand, the same problem exists in mpl::for_each. The unary functor passed to mpl::for_each looks like: struct F { template <typename T> void operator()(T) { .... } }; mpl::for_each<seq>(F()); so T is deduced by the argument being passed. T is constructed (probably default constructed) and then sent to the functor. Since we usually don't want to instantiate the types in the MPL sequence, we use a transform meta-function. Something like: struct F { template <typename T> void operator()(mpl::identity<T>) { .... } }; mpl::for_each<seq, mpl::make_identity<_> >(F()); and then the T's being instantiated are not the types in the sequence, but mpl::identity<> of the types in the sequence, which is much better. The solution proposed here could probably be extended to support transform meta-functions just like mpl::for_each does, and the problem is solved. I sure hope this (or similar) mpl::for_each_until will be added to MPL. I also find it useful. As I said, I'm not an expert, so I hope I'm not misleading anyone here...