[mpl] Using transform problem and solution

I have a boost::mpl::vector of nullary metafunctions and I need to transform it into a sequence of the metafunction's inner types. As in: typedef boost::mpl::vector<boost::mpl::identity<int> > tvec; typedef boost::mpl::vector<int> tvecinner; So I try boost::mpl::transform: typedef typename boost::mpl::transform<tvec,_1>::type ttrans; BOOST_MPL_ASSERT((boost::mpl::equal<tvecinner,ttrans>)); But that does not work and the assert fails. Evidently my _1 is not working by itself although it seems as if it should because it is a placeholder expression and its inner type is what I want. So I try: template <class T> struct tself : T { }; and now instead: typedef typename boost::mpl::transform<tvec,tself<_1> >::type ttrans; BOOST_MPL_ASSERT((boost::mpl::equal<tvecinner,ttrans>)); works fine and the assert succeeds. But that 'tself' hack seems like it should be really unnecessary. Have I missed something cleaner and easier ?

AMDG On 1/27/2011 6:04 PM, Edward Diener wrote:
I have a boost::mpl::vector of nullary metafunctions and I need to transform it into a sequence of the metafunction's inner types. As in:
typedef boost::mpl::vector<boost::mpl::identity<int> > tvec; typedef boost::mpl::vector<int> tvecinner;
So I try boost::mpl::transform:
typedef typename boost::mpl::transform<tvec,_1>::type ttrans; BOOST_MPL_ASSERT((boost::mpl::equal<tvecinner,ttrans>));
But that does not work and the assert fails. Evidently my _1 is not working by itself although it seems as if it should because it is a placeholder expression and its inner type is what I want.
I would say that the behavior of MPL is correct. Consider what would happen with the runtime Lambda: _1(f) -> f bind(_1)(f) -> f() Here also, using _1 by itself isn't enough to trigger evaluation.
So I try:
template <class T> struct tself : T { };
and now instead:
typedef typename boost::mpl::transform<tvec,tself<_1> >::type ttrans; BOOST_MPL_ASSERT((boost::mpl::equal<tvecinner,ttrans>));
works fine and the assert succeeds.
But that 'tself' hack seems like it should be really unnecessary. Have I missed something cleaner and easier ?
mpl::apply<_1>? In Christ, Steven Watanabe

On 1/27/2011 9:15 PM, Steven Watanabe wrote:
AMDG
On 1/27/2011 6:04 PM, Edward Diener wrote:
I have a boost::mpl::vector of nullary metafunctions and I need to transform it into a sequence of the metafunction's inner types. As in:
typedef boost::mpl::vector<boost::mpl::identity<int> > tvec; typedef boost::mpl::vector<int> tvecinner;
So I try boost::mpl::transform:
typedef typename boost::mpl::transform<tvec,_1>::type ttrans; BOOST_MPL_ASSERT((boost::mpl::equal<tvecinner,ttrans>));
But that does not work and the assert fails. Evidently my _1 is not working by itself although it seems as if it should because it is a placeholder expression and its inner type is what I want.
I would say that the behavior of MPL is correct. Consider what would happen with the runtime Lambda:
_1(f) -> f bind(_1)(f) -> f()
Here also, using _1 by itself isn't enough to trigger evaluation.
I am not sure what the two expressions above are supposed to do, but I will take your word for it that just using _1 does not trigger evaluation since evidently it does not in my case.
So I try:
template <class T> struct tself : T { };
and now instead:
typedef typename boost::mpl::transform<tvec,tself<_1> >::type ttrans; BOOST_MPL_ASSERT((boost::mpl::equal<tvecinner,ttrans>));
works fine and the assert succeeds.
But that 'tself' hack seems like it should be really unnecessary. Have I missed something cleaner and easier ?
mpl::apply<_1>?
My _1 is a metafunction, not a metafunction class so that does not work. I guess what I see as my "hack" is the correct solution. It just seemed funny using it. I had previously asked in other thread whether MPL has a metafunction which takes a nullary metafunction and returns the nullary metafunction's inner type, and was correctly asked why I would need something like that. I replied that indeed I should not and my thinking was muddled when I asked the question. But here is a case where it is evidently needed and my 'tself' is the solution. But it still feels like a real "hack" which somehow should never be necessary, but evidently is necessary in my case.

2011/1/28 Edward Diener <eldiener@tropicsoft.com>
So I try:
template <class T> struct tself : T { };
You did the right thing, and it would be more clear to define it as:
namespace intrinsic { template <class T> struct type { typedef typename T::type type; }; } And used as: typedef typename boost::mpl::transform<tvec, intrinsic::type<_1> >::type ttrans; which makes more sense to me.
participants (3)
-
Edward Diener
-
Steven Watanabe
-
TONGARI