template metaprogramming evaluation
Asked Answered
L

1

7

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?

Lyrebird answered 24/5, 2012 at 23:29 Comment(0)
A
11

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.

Arda answered 24/5, 2012 at 23:48 Comment(4)
Thanks! That worked, using the lazy if makes sense but I don't really understand why you need the identity<T> and extract_element_type<T>?Lyrebird
@Lyrebird : Rather than types directly like if_, eval_if takes unary metafunctions that produce types. That lazy evaluation/instantiation of said metafunctions is what makes it work the way you need.Arda
Ahh, this is my first time using MPL, who knew it could be so convoluted?Lyrebird
@Lyrebird It gets much worse! :PComose

© 2022 - 2024 — McMap. All rights reserved.