[mpl] Placeholders substitution and template partial specialization

Hi All Consider following example: BOOST_MPL_ASSERT((boost::is_same< mpl::apply<mpl::apply<_1, _2>::type, boost::add_pointer<_1>, int>::type , int*>)); It should apply "add_pointer" to "int" and receive "int*", but it doesn't work. It returns just "int". Consider another example: template <class F, class X> struct apply1: mpl::lambda<F>::type::template apply<X> {}; BOOST_MPL_ASSERT((boost::is_same< mpl::apply<apply1<mpl::_1, mpl::_2>/*nothing here*/, boost::add_pointer<mpl::_1>, int>::type , int*>)); Handmade apply1 is used instead of mpl::apply. And this example works. What difference? Usage of nested "::type" of apply metafunction. As result: BOOST_MPL_ASSERT((boost::is_same< mpl::apply<apply1<mpl::_1, mpl::_2>::type, boost::add_pointer<mpl::_1>, int>::type , int*>)); doesn't work. Seems like this change affects time of placeholders substitution. Can anybody explain this in detail? So, since apply1 is just simplified version of mpl::apply, why we cannot use mpl::apply w/o "::type"? Because it cannot be compiled, at least using VC8. And seems like the main difference is that apply1 is primary template but mpl::apply is partial template specialization. Is such behavior standard? Can anybody explain the logic? Best regards, Andriy Tylychko, telya@mail.ru

Andriy Tylychko writes:
Consider following example:
BOOST_MPL_ASSERT((boost::is_same< mpl::apply<mpl::apply<_1, _2>::type, boost::add_pointer<_1>, int>::type , int*>));
It should apply "add_pointer" to "int" and receive "int*", but it doesn't work. It returns just "int".
Consider another example:
template <class F, class X> struct apply1:
mpl::lambda<F>::type::template apply<X> {};
BOOST_MPL_ASSERT((boost::is_same< mpl::apply<apply1<mpl::_1, mpl::_2>/*nothing here*/, boost::add_pointer<mpl::_1>, int>::type , int*>));
Handmade apply1 is used instead of mpl::apply. And this example works. What difference? Usage of nested "::type" of apply metafunction. As result:
BOOST_MPL_ASSERT((boost::is_same< mpl::apply<apply1<mpl::_1, mpl::_2>::type, boost::add_pointer<mpl::_1>, int>::type , int*>));
doesn't work. Seems like this change affects time of placeholders substitution. Can anybody explain this in detail?
So, since apply1 is just simplified version of mpl::apply, why we cannot use mpl::apply w/o "::type"? Because it cannot be compiled, at least using VC8. And seems like the main difference is that apply1 is primary template but mpl::apply is partial template specialization. Is such behavior standard? Can anybody explain the logic?
There is not much logic here: it's simply a (known) bug. Please see http://thread.gmane.org/gmane.comp.lib.boost.user/9699 for more details. -- Aleksey Gurtovoy MetaCommunications Engineering
participants (2)
-
Aleksey Gurtovoy
-
Andriy Tylychko (mail.ru)