Opened 12 years ago

Closed 4 years ago

#5490 closed Bugs (fixed)

Fusion fails to insulate user-supplied template parameters from unintentional MPL placeholder substitution (?)

Reported by: Jeffrey Hellrung <jeffrey.hellrung@…> Owned by: Kohei Takahashi
Milestone: Boost 1.68.0 Component: fusion
Version: Boost 1.47.0 Severity: Problem
Keywords: fusion, mpl, placeholder, substitution Cc:

Description

The code below fails on MSVC9 with Boost 1.43.0, but recent developers' list activity [1] suggests this is still broken in Boost 1.46.1. And, to emphasize, I believe it *should* compile, but I could be wrong there!

#include <iostream>

#include <boost/fusion/algorithm/transformation/transform.hpp>
#include <boost/fusion/container/vector/vector10.hpp>
#include <boost/fusion/sequence/io/out.hpp>
#include <boost/mpl/quote.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/type_traits/is_integral.hpp>

template< class >
struct foo
{
    typedef int result_type;
    template< class T >
    int operator()(const T&) const
    { return 0; }
};


int main()
{
    boost::fusion::vector1< int > v;
    typedef boost::is_integral< boost::mpl::_1 > mpl_type; // 1
    //typedef boost::mpl::quote1< boost::is_integral > mpl_type; // 2
    std::cout << boost::fusion::transform(v, foo< mpl_type >());

    return 0;
}

A workaround is to use " 2" rather than " 1".

I believe the proper fix is to insulate any user-supplied template parameters from unintential Boost.MPL placeholder substitution within the implementation of boost::fusion::transform and/or boost::fusion::transform_view, but I haven't looked into where exactly this should occur or how widespread this is.

The existence of a workaround together with the probable rarity of the situation likely makes this a low-priority bug, but it is a subtle problem once you run into it.

[1] http://thread.gmane.org/gmane.comp.lib.boost.devel/218162

Change History (4)

comment:1 by Kohei Takahashi <flast@…>, 7 years ago

Does the quoted version (i.e. "2") work as you intended? It instantiate foo<quote1<is_integral>> but not foo<true_> or foo<false_> because foo<is_integral<_1>> and quote1<is_integral> are lambda expression, but foo<quote1<is_integral>> is not.

see: http://melpon.org/wandbox/permlink/5rAG4sqeTJPcqtDe

comment:2 by Kohei Takahashi, 4 years ago

Owner: changed from Joel de Guzman to Kohei Takahashi

Ahhhh, OK, I understood what you said. The functor of fusion::transform doesn't require MPL lambda expression, thus the MPL substitution should not be performed.

comment:4 by Kohei Takahashi, 4 years ago

Milestone: To Be DeterminedBoost 1.68.0
Resolution: fixed
Status: newclosed
Note: See TracTickets for help on using tickets.