MPL if_ not following true branch
This code doesn't seem to ever follow the true branch of the if_... it's like the eval_if is clobbering it. Can someone tell me what I'm doing wrong (other than not using a map.. this is a reduction of some other code that can't use a map)? #include <iostream> #include <typeinfo> #include <boost/mpl/if.hpp> #include <boost/mpl/eval_if.hpp> #include <boost/mpl/identity.hpp> #include <boost/type_traits/is_same.hpp> #include <boost/static_assert.hpp> template<typename T> struct choose_type { struct int_tag {}; struct float_tag {}; template<typename InvalidT> struct invalid_type_specified { BOOST_STATIC_ASSERT(sizeof(InvalidT) == 0); }; typedef typename boost::mpl::if_< boost::is_same<T, int>, int_tag, typename boost::mpl::eval_if< boost::is_same<T, float>, boost::mpl::identity<float_tag>, invalid_type_specified<T> >::type >::type type; }; int main() { std::cout << typeid(choose_type<int>::type).name() << std::endl; return 0; } -- Cory Nelson
Cory Nelson escribió:
This code doesn't seem to ever follow the true branch of the if_... it's like the eval_if is clobbering it. Can someone tell me what I'm doing wrong (other than not using a map.. this is a reduction of some other code that can't use a map)?
#include <iostream> #include <typeinfo> #include <boost/mpl/if.hpp> #include <boost/mpl/eval_if.hpp> #include <boost/mpl/identity.hpp> #include <boost/type_traits/is_same.hpp> #include <boost/static_assert.hpp>
template<typename T> struct choose_type { struct int_tag {}; struct float_tag {};
template<typename InvalidT> struct invalid_type_specified { BOOST_STATIC_ASSERT(sizeof(InvalidT) == 0); };
typedef typename boost::mpl::if_< boost::is_same<T, int>, int_tag, typename boost::mpl::eval_if< boost::is_same<T, float>, boost::mpl::identity<float_tag>, invalid_type_specified<T> >::type
::type type; };
The problem with your code is that the else part of your mpl::if_ expression is always evaluated (it has the form mpl::eval_if<...>::type), so when you you instantiate choose_type<int> the mpl::eval_if_ is also instantiated and static asserts (as int is not float). Try this instead: struct choose_type { struct int_tag {}; struct float_tag {}; template<typename InvalidT> struct invalid_type_specified { BOOST_STATIC_ASSERT(sizeof(InvalidT) == 0); }; typedef typename boost::mpl::eval_if< boost::is_same<T, int>, boost::mpl::identity<int_tag>, typename boost::mpl::eval_if< boost::is_same<T, float>, boost::mpl::identity<float_tag>, invalid_type_specified<T> > >::type type; }; Joaquín M López Muñoz Telefónica, Investigación y Desarrollo
participants (2)
-
Cory Nelson
-
joaquin@tid.es