on Wed Mar 28 2007, Scott Meyers <usenet-AT-aristeia.com> wrote:
JOAQUIN LOPEZ MU?Z wrote:
I think you want to write
mpl::end<Constraints>::type
Thanks for the suggestion, but it doesn't change the behavior of the program: the result of the insertion of a new element into the two-element set is a new set with only two elements (one of the original elements is lost). Please try it and see if you get the same thing I do.
Scott, I hate to say this, but I really think your first problem demonstrated that mpl::set is too broken to use. I've asked Aleksey to look at it, but he's not answering (maybe on vacation, I dunno). I'd like to fix it myself as I was the one who came up with the basic mechanisms for mpl::set, but unfortunately I can't tell what Aleksey intended in his realization of those ideas so I'm not quite sure where to start. You might see if you can use mpl::map to do the same things.
Well, excuse me if the following is obvious to you, but ::type is to a metafunction what actual invocation is to a run-time function. So, mpl::end<Constraints> refers to the name of the entity, but does not actually compute its "return value" unless you add the ::type suffix.
I don't think this always holds.
Yeah, it always holds.
For example, I don't need to add the ::type suffix when I make a typedef or when I do an assertion:
typedef mpl::set<A, B> MySet;
There's no metafunction invocation there; you're just stating the name ofa type (mpl::set<A,B>). mpl::set<...> may actually have a ::type member (essentially a typedef for mpl::set<...> itself), but if so it's just there as a convenience for use with constructs like eval_if. mpl::eval_if< predicate , some_metafunction_to_be_evaluated_if_pred_true<X> , mpl::set< ... > > it prevents you from having to write mpl::eval_if< predicate , some_metafunction_to_be_evaluated_if_pred_true<X> , mpl::identity<mpl::set< ... > > ^^^^^^^^^^^^^ >
BOOST_MPL_ASSERT(( mpl::equal<mpl::set<A,B>, mpl::set<A,B> > ));
No explicit metafunction invocation there either... at least, not by you. Again, you're just stating the name of a type: mpl::equal<mpl::set<A,B>, mpl::set<A,B> > That type happens to be a nullary metafunction (any N-ary metafunction, where N>0, with all its arguments filled in, is a nullary metafunction: a class with a nested ::type). Actually the extra set of parens is used by MPL to form a function type: int (mpl::equal<mpl::set<A,B>, mpl::set<A,B> >) MPL strips the int(...) off to get your nullary metafunction, and then it invokes that. Just as with the 2nd or 3rd argument to mpl::eval_if. There's a class of metafunctions that usually don't need to be explicitly invoked: those whose range of results is limited in certain ways. In practice this turns out to mean metafunctions with numeric/boolean results. For example, I could write a metafunction to square a numeric value like this: template <class N> struct square : mpl::integral_c< N::value_type, N::type::value*N::type::value > {}; In what sense is that a metafunction? Well, all MPL IntegralConstants contain a nested ::type returning an equivalent IntegralConstant. So integral_c looks like: template <class T, T x> struct integral_c { typedef T value_type; static T const value = x; typedef integral_c<T,x> type; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ }; So integral_c<U,v> is a self-returning nullary metafunction (reach inside to get its ::type, you get itself back). And square<X> inherits most of those properties... enough to make it a conforming IntegralConstant. As a result, you could write mpl::add< square<mpl::int_<3> >::type, mpl::int_<1> >::type ^^^^^^ or mpl::add< square<mpl::int_<3> >, mpl::int_<1> >::type and you'd get the same result. The same applies to all the Boost/TR1 type traits with their boolean result types. That's why you can write either: mpl::if_< boost::is_pointer<X>::type , T // ^^^^^^ , F >::type or mpl::if_< boost::is_pointer<X> // no ::type , T , F >::type and get the same result. Incidentally, it's possible to construct a C++ template metaprogramming system in which ::type (and typename!) is needed much less frequently (http://aspn.activestate.com/ASPN/Mail/Message/boost/2259201). I think Vesa's approach had a lot of promise and I wish we'd had time to pursue it. -- Dave Abrahams Boost Consulting www.boost-consulting.com Don't Miss BoostCon 2007! ==> http://www.boostcon.com