3
votes

When I try the mpl::bind function with following test code, I failed to pass compiler in gcc, could someone help me to track out the problems, many thanks.

#include <iostream>
#include <typeinfo>
#include <string>
#include <boost/mpl/apply.hpp>
#include <boost/mpl/char.hpp>
#include <boost/mpl/int.hpp>
#include <boost/mpl/arg.hpp>
#include <boost/mpl/plus.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/add_pointer.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/mpl/quote.hpp>

using namespace std;

using namespace boost::mpl;

template< typename T1,typename T2 >
struct int_plus:boost::mpl::int_< (T1::value+T2::value) >
{
};

int main()
{
    typedef boost::mpl::lambda< int_plus<_1, _2 > >::type test1;        //-fine

    // test2 define is causeing error
    typedef boost::mpl::bind  < int_plus<_1, _2 > > test2;              //-error?

    typedef boost::mpl::lambda< quote2<int_plus>, _2, _1 >::type test3; //-fine
    typedef boost::mpl::bind< quote2<int_plus>, _2, _1 > test4;         //-fine
    typedef test1::apply<int_<42>, int_<23>>::type test5;               //-fine
    typedef test2::apply<int_<42>, int_<23>>::type test6;               //-error
    typedef test3::apply<int_<42>, int_<24>>::type test7;               //-fine
    typedef test4::apply<int_<42>, int_<24>>::type test8;               //-fine
    BOOST_MPL_ASSERT_RELATION( test5::value, ==, 65 );                  //-fine
    //BOOST_MPL_ASSERT_RELATION( test6::value, ==, 65 );
}

the error message:

||=== Build: Debug in jtest2 (compiler: GNU GCC Compiler) ===|

C:\boost\mpl\aux_\preprocessed\gcc\apply_wrap.hpp||In instantiation of 'struct boost::mpl::apply_wrap0, mpl_::arg<2> >, mpl_::bool_ >':|

C:\boost\mpl\aux_\preprocessed\gcc\bind.hpp|86|required from 'struct boost::mpl::bind0, mpl_::arg<2> > >::apply, mpl_::int_<23> >'| C:\ls\jtest2\main.cpp|30|required from here|

C:\boost\mpl\aux_\preprocessed\gcc\apply_wrap.hpp|20|error: no class template named 'apply' in 'struct int_plus, mpl_::arg<2> >'|

C:\boost\mpl\aux_\preprocessed\gcc\bind.hpp||In instantiation of 'struct boost::mpl::bind0, mpl_::arg<2> > >::apply, mpl_::int_<23> >':|

C:\ls\jtest2\main.cpp|30|required from here| C:\boost\mpl\aux_\preprocessed\gcc\bind.hpp|86|error: no type named 'type' in 'struct boost::mpl::apply_wrap0, mpl_::arg<2> >, mpl_::bool_ >'|

||=== Build failed: 2 error(s), 5 warning(s) (0 minute(s), 0 second(s)) ===|

1
Can you post the full error message? What's you've shown is just information about where the compiler was instantiating templates when it encountered an error.SirGuy
Doesn't test4 solve the issue you've got with test2?Igor R.
yes, the test4 works fine and both test1, test3 works. I couldn't understand the test2, maybe I steal check more about the the mpl::bindshavian
I have updated the question to include the full test code and error message.shavian

1 Answers

1
votes

After checking the defines and semantics of bind, it need a metafunction class as the first parameter , that means the metafunction could not work;

We have several methods to convert the metafunction to the matafunction class, in this example the metafunction int_plus could be covert by

1) quote2(int_plus)

2) int_plus_f

3) int_plus_f2

#include <iostream>
#include <typeinfo>
#include <string>
#include <boost/mpl/apply.hpp>
#include <boost/mpl/char.hpp>
#include <boost/mpl/int.hpp>
#include <boost/mpl/arg.hpp>
#include <boost/mpl/plus.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/add_pointer.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/mpl/quote.hpp>

using namespace std;
using namespace boost::mpl;

template< typename T1,typename T2 >
struct int_plus:boost::mpl::int_< (T1::value+T2::value) >
{
};

struct int_plus_f  // method 1 to get metafunction class, not perfect for lambda
{
    template< typename T1,typename T2 >
    struct apply:boost::mpl::int_< (T1::value+T2::value) >
    {
    };
};

struct int_plus_f2 // method 2 to get metafunction class, perfect for lambda
{
    template< typename A1, typename A2 > struct apply
            : int_plus<A1,A2>
    {
    };
};

int main()
{
    //bind define:
    //    typedef bind<f,a1,...an> g;
    //bind parameters:
    //    F Metafunction Class An metafunction class to perform binding on.
    //    A1,... An Any type Arguments to bind.

    //lambda define:
    //    typedef lambda<x>::type f;
    //    typedef lambda<x,Tag>::type f;
    //lambda parameters
    //    X Any type An expression to transform.
    //    Tag Any type A tag determining transform semantics
    //lambda Semantics equivalent to
    //    typedef protect< bind< quoten<X> , lambda<a1>::type,... lambda<an>::type > > f;
    //quote define:
    //    typedef quoten<f> g;
    //    typedef quoten<f,tag> g;
    //quote2 Semantics Equivalent to
    //    struct g{
    //        template< typename A1,typename A2 >
    //            struct apply : f<A1,A2>{};
    //            };




    typedef boost::mpl::lambda< int_plus<_1, _2 > >::type test1;        //-fine
    typedef boost::mpl::bind  < int_plus_f,_1, _2  > test2;             //-fine
    typedef boost::mpl::bind  < int_plus_f2,_1, _2  > test3;            //-fine
    typedef boost::mpl::lambda< int_plus_f2,_1, _2  >::type test4;      //-fine
    typedef boost::mpl::lambda< quote2<int_plus>, _2, _1 >::type test5; //-fine
    typedef boost::mpl::bind< quote2<int_plus>, _2, _1 > test6;         //-fine
    typedef test1::apply<int_<42>, int_<22>>::type result1;             //-fine
    typedef test2::apply<int_<42>, int_<23>>::type result2;             //-fine
    typedef test3::apply<int_<42>, int_<24>>::type result3;             //-fine
    typedef test4::apply<int_<42>, int_<25>>::type result4;             //-fine
    typedef test5::apply<int_<42>, int_<26>>::type result5;             //-fine
    typedef test6::apply<int_<42>, int_<27>>::type result6;             //-fine
    BOOST_MPL_ASSERT_RELATION( result1::value, ==, 64 );                //-fine
    BOOST_MPL_ASSERT_RELATION( result2::value, ==, 65 );                //-fine
    BOOST_MPL_ASSERT_RELATION( result3::value, ==, 66 );                //-fine
    BOOST_MPL_ASSERT_RELATION( result4::value, ==, 67 );                //-fine
    BOOST_MPL_ASSERT_RELATION( result5::value, ==, 68 );                //-fine
    BOOST_MPL_ASSERT_RELATION( result6::value, ==, 69 );                //-fine


    //apply :  Invokes a Metafunction Class or a Lambda Expression F with arguments A1,... An.
    //    typedef apply<f,a1,...an>::type t;
    //apply parameters
    //    F Lambda Expression: An expression(e.g.: a metafunction) to invoke,
    //      metafunction class is fine also
    //    A1,... An Any type Invocation arguments.
    // apply  Semantics Equivalent to
    //    typedef apply_wrapn< lambda<f>::type,a1,... an>::type t;.

    typedef apply< int_plus<_1,_2>, int_<2>, int_<3> >::type r1;
    typedef apply< quote2<int_plus>, int_<2>, int_<3> >::type r2;
    typedef apply< int_plus_f, int_<2>, int_<3> >::type r3;
    typedef apply< int_plus_f2, int_<2>, int_<3> >::type r4;

    BOOST_MPL_ASSERT_RELATION( r1::value, ==, 5 );
    BOOST_MPL_ASSERT_RELATION( r2::value, ==, 5 );
    BOOST_MPL_ASSERT_RELATION( r3::value, ==, 5 );
    BOOST_MPL_ASSERT_RELATION( r4::value, ==, 5 );

}