Visual C++ does not recognize lambda metafunction as such

I just tried to build this code in visual studio 2005, and got error: error C3201: the template parameter list for class template 'boost::mpl::bind2<F,T1,T2>::apply' does not match the template parameter list for template parameter 'boolfunc' This code works fine with gcc, and boost mpl portability page (http://www.boost.org/libs/mpl/doc/tutorial/portability.html) says my version of visual studio should be able to compile this. However, it appears to think the lambda< ... >::type::apply is not a metafunction. Any help will be greatly appreciated. -Matt Brown #include <iostream> #include <boost/mpl/lambda.hpp> #include <boost/type_traits/is_same.hpp> #include <boost/mpl/placeholders.hpp> template <template <typename> class boolfunc> class test { public: static void print() { if(boolfunc<int>::type::value) { std::cout << "int: true\n"; } } }; int main(void) { test< boost::mpl::lambda< boost::is_same<boost::mpl::_1, int> >::type::apply >::print(); };

AMDG Matt Brown wrote:
I just tried to build this code in visual studio 2005, and got error:
error C3201: the template parameter list for class template 'boost::mpl::bind2<F,T1,T2>::apply' does not match the template parameter list for template parameter 'boolfunc'
This code works fine with gcc, and boost mpl portability page (http://www.boost.org/libs/mpl/doc/tutorial/portability.html) says my version of visual studio should be able to compile this. However, it appears to think the lambda< ... >::type::apply is not a metafunction. Any help will be greatly appreciated.
-Matt Brown
#include <iostream> #include <boost/mpl/lambda.hpp> #include <boost/type_traits/is_same.hpp> #include <boost/mpl/placeholders.hpp>
template <template <typename> class boolfunc> class test { public: static void print() { if(boolfunc<int>::type::value) { std::cout << "int: true\n"; } } };
int main(void) { test< boost::mpl::lambda< boost::is_same<boost::mpl::_1, int> >::type::apply >::print(); };
Don't do that. boost::mpl::lambda< boost::is_same<boost::mpl::_1, int> >::type::apply<int>::type will work, but apply actually takes extra default arguments and thus cannot be bound to a template template argument. i.e. (For exposition only) template<class T> struct lambda { struct type { template<class T0 = na, class T1 = na, ...> struct apply { typedef /unspecified/ type; }; }; }; In Christ, Steven Watanabe

Thanks for the reply, Steven. You were able to give me enough direction to solve the problem. I simply had to write a wrapper class around apply that had the correct template signature. template <typename MetaFunc> struct apply1 { template <typename T> struct apply : MetaFunc::apply<T> {}; }; int main(void) { test< apply1< boost::mpl::lambda< boost::is_same<boost::mpl::_1, int> >::type >::apply >::print(); }; I've gotta say, though, that this behavior of MPL's lambda, bind, quoten, etc Meftafunctions is counter intuitive (to put it nicely). The runtime bind library, as a counter example, is intuitive. When you bind one argument to a second order function, you get a first order function. If the runtime bind library was designed similar to the bind facility in MPL, it would give you a function with a variable argument list, which I believe anyone would agree is counter intuitive. I'm sure there is a good reason MPL was designed this way, though I doubt its a better reason than the reason it should have been designed intuitively. -Matt On Thu, Mar 13, 2008 at 9:31 AM, Steven Watanabe <watanabesj@gmail.com> wrote:
AMDG
Matt Brown wrote:
I just tried to build this code in visual studio 2005, and got error:
error C3201: the template parameter list for class template 'boost::mpl::bind2<F,T1,T2>::apply' does not match the template parameter list for template parameter 'boolfunc'
This code works fine with gcc, and boost mpl portability page (http://www.boost.org/libs/mpl/doc/tutorial/portability.html) says my version of visual studio should be able to compile this. However, it appears to think the lambda< ... >::type::apply is not a metafunction. Any help will be greatly appreciated.
-Matt Brown
#include <iostream> #include <boost/mpl/lambda.hpp> #include <boost/type_traits/is_same.hpp> #include <boost/mpl/placeholders.hpp>
template <template <typename> class boolfunc> class test { public: static void print() { if(boolfunc<int>::type::value) { std::cout << "int: true\n"; } } };
int main(void) { test< boost::mpl::lambda< boost::is_same<boost::mpl::_1, int> >::type::apply >::print(); };
Don't do that.
boost::mpl::lambda< boost::is_same<boost::mpl::_1, int> >::type::apply<int>::type
will work, but apply actually takes extra default arguments and thus cannot be bound to a template template argument.
i.e. (For exposition only)
template<class T> struct lambda { struct type { template<class T0 = na, class T1 = na, ...> struct apply { typedef /unspecified/ type; }; }; };
In Christ, Steven Watanabe
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users

AMDG Matt Brown wrote:
Thanks for the reply, Steven. You were able to give me enough direction to solve the problem. I simply had to write a wrapper class around apply that had the correct template signature.
template <typename MetaFunc> struct apply1 { template <typename T> struct apply : MetaFunc::apply<T> {}; };
int main(void) { test< apply1< boost::mpl::lambda< boost::is_same<boost::mpl::_1, int> >::type >::apply
::print(); };
I've gotta say, though, that this behavior of MPL's lambda, bind, quoten, etc Meftafunctions is counter intuitive (to put it nicely). The runtime bind library, as a counter example, is intuitive. When you bind one argument to a second order function, you get a first order function. If the runtime bind library was designed similar to the bind facility in MPL, it would give you a function with a variable argument list, which I believe anyone would agree is counter intuitive. I'm sure there is a good reason MPL was designed this way, though I doubt its a better reason than the reason it should have been designed intuitively.
As a matter of fact the runtime bind library /does/ give you a function object that can take a variable number of arguments. boost::bind(std::plus<int>(), _1, _1)(0, 2, 1, 3, 4); // OK. extra arguments ignored. What you're trying to do with MPL is the equivalent of saying: int (*f)(int, int) = boost::bind(std::plus<int>(), _1, _2); Which of course will not work. In short you can use the nested apply template, but there are no guarantees about exactly how it is defined. The MPL way of achieving your end is to pass metafunction classes around rather than template template arguments. #include <iostream> #include <boost/mpl/lambda.hpp> #include <boost/mpl/apply.hpp> #include <boost/type_traits/is_same.hpp> #include <boost/mpl/placeholders.hpp> template <class boolfunc> class test { public: static void print() { if(mpl::apply1<boolfunc, int>::type::value) { std::cout << "int: true\n"; } } }; int main(void) { test< boost::mpl::lambda< boost::is_same<boost::mpl::_1, int> >::type >::print(); }; In Christ, Steven Watanabe

ah, I understand. thanks again. On Thu, Mar 13, 2008 at 1:04 PM, Steven Watanabe <watanabesj@gmail.com> wrote:
AMDG
Matt Brown wrote:
Thanks for the reply, Steven. You were able to give me enough direction to solve the problem. I simply had to write a wrapper class around apply that had the correct template signature.
template <typename MetaFunc> struct apply1 { template <typename T> struct apply : MetaFunc::apply<T> {}; };
int main(void) { test< apply1< boost::mpl::lambda< boost::is_same<boost::mpl::_1, int> >::type >::apply >::print(); };
I've gotta say, though, that this behavior of MPL's lambda, bind, quoten, etc Meftafunctions is counter intuitive (to put it nicely). The runtime bind library, as a counter example, is intuitive. When you bind one argument to a second order function, you get a first order function. If the runtime bind library was designed similar to the bind facility in MPL, it would give you a function with a variable argument list, which I believe anyone would agree is counter intuitive. I'm sure there is a good reason MPL was designed this way, though I doubt its a better reason than the reason it should have been designed intuitively.
As a matter of fact the runtime bind library /does/ give you a function object that can take a variable number of arguments.
boost::bind(std::plus<int>(), _1, _1)(0, 2, 1, 3, 4); // OK. extra arguments ignored.
What you're trying to do with MPL is the equivalent of saying:
int (*f)(int, int) = boost::bind(std::plus<int>(), _1, _2);
Which of course will not work.
In short you can use the nested apply template, but there are no guarantees about exactly how it is defined. The MPL way of achieving your end is to pass metafunction classes around rather than template template arguments.
#include <iostream> #include <boost/mpl/lambda.hpp> #include <boost/mpl/apply.hpp>
#include <boost/type_traits/is_same.hpp> #include <boost/mpl/placeholders.hpp>
template <class boolfunc>
class test { public: static void print() { if(mpl::apply1<boolfunc, int>::type::value)
{ std::cout << "int: true\n"; } } };
int main(void) { test< boost::mpl::lambda< boost::is_same<boost::mpl::_1, int> >::type >::print();
};
In Christ, Steven Watanabe
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
participants (2)
-
Matt Brown
-
Steven Watanabe