оценка метапрограммирования шаблона

Итак, у меня есть класс шаблона, который я хотел бы принять std::map, где тип данных является либо необработанным указателем, либо std::unique_ptr. Затем в этом классе я хотел бы получить тип базового указателя:

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

Однако я получаю следующую ошибку при создании экземпляра класса с использованием карты с необработанным типом указателя:

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

Мне кажется, что он оценивает typename Container::mapped_type::element_type* по необработанному указателю, я думал, что с метапрограммированием шаблона он не оценит это, когда if_ преуспеет. Должен ли я идти об этом по-другому?


person grivescorbett    schedule 24.05.2012    source источник


Ответы (1)


Вам нужен ленивый if попробуйте boost::mpl::eval_if вместо 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;
};

То есть, если вы сомневаетесь, добавьте дополнительный уровень косвенности.

person ildjarn    schedule 24.05.2012
comment
Спасибо! Это сработало, использование ленивого if имеет смысл, но я действительно не понимаю, зачем вам нужны идентификаторы «T» и «extract_element_type» «T»? - person grivescorbett; 25.05.2012
comment
@grivescorbett: вместо таких типов, как if_, eval_if принимает унарные метафункции, которые производят типы. Эта ленивая оценка/создание указанных метафункций - вот что заставляет его работать так, как вам нужно. - person ildjarn; 25.05.2012
comment
Ах, я впервые использую MPL, кто знал, что это может быть так запутанно? - person grivescorbett; 25.05.2012
comment
@grivescorbett Становится намного хуже! :П - person aldo; 27.05.2012