Metaprogramming Evaluation Templates

So, I have a template class that I would like to accept std :: map, where the data type is either a raw pointer or std :: unique_ptr. Then in this class I would like to get the type of the base pointer:

typedef typename boost::mpl::if_< boost::is_pointer<typename Container::mapped_type>, typename Container::mapped_type, typename Container::mapped_type::element_type* >::type data_type 

However, I get the following error when instantiating a class using a map with a raw pointer type:

 error: 'std::map<int, ValueType*>::mapped_type {aka ValueType*}' is not a class, struct, or union type 

It seems to me that it evaluates typename Container::mapped_type::element_type* on a raw pointer, I thought that with template metaprogramming, it would not evaluate this when if_ succeeded. Should I go about it differently?

+7
source share
1 answer

You need a lazy if - try boost::mpl::eval_if instead of boost::mpl::if_ :

 #include <boost/type_traits/is_pointer.hpp> #include <boost/mpl/eval_if.hpp> #include <boost/mpl/identity.hpp> template<typename T> struct extract_element_type { typedef typename T::element_type* type; }; template<typename Container> struct foo { typedef typename boost::mpl::eval_if< boost::is_pointer<typename Container::mapped_type>, boost::mpl::identity<typename Container::mapped_type>, extract_element_type<typename Container::mapped_type> >::type data_type; }; 

Ie, when in doubt, add an extra layer of indirection.

+11
source

All Articles