template metaprogramming evaluation
boost, boost-mpl, c++, template-meta-programming
Solution
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;
};
I.e., when in doubt, add an extra layer of indirection.
Problem
So I have a template class that I would like to accept an std::map where the data type is either a raw pointer or an std::unique_ptr. Then in this class I would like to get the type of the underlying 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 the 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 like it is evaluating `typename Container::mapped_type::element_type*` on the raw pointer, I thought that with template metaprogramming it would not evaluate that when the if_ succeeded. Should I be going about this a different way?