2012-05-24 15 views
7

Quindi ho una classe template che vorrei accettare una std :: map in cui il tipo di dati è un puntatore raw o uno std :: unique_ptr. Poi in questa classe mi piacerebbe ottenere il tipo del puntatore sottostante:valutazione metaprogramming modello

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 

Tuttavia ottengo il seguente errore quando si crea un'istanza della classe utilizzando una mappa con un tipo di puntatore RAW:

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

E ' mi sembra che stia valutando typename Container::mapped_type::element_type* sul puntatore raw, ho pensato che con il modello metaprogramming non sarebbe stato valutato quando if_ fosse riuscito. Dovrei andare in questo modo in un modo diverso?

risposta

11

Hai bisogno di un pigroif – provare boost::mpl::eval_if invece di 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; 
}; 

cioè in caso di dubbio, aggiungere un ulteriore livello di riferimento indiretto.

+1

Grazie! Ha funzionato, usare i pigri se ha senso ma non capisco davvero perché hai bisogno dell'identità e extract_element_type ? – grivescorbett

+1

@grivescorbett: Piuttosto che i tipi direttamente come 'if_',' eval_if' utilizza metafunzionamenti unari che _produce_ types. Quella pigra valutazione/istanziazione di dette metafunzioni è ciò che fa funzionare il modo in cui è necessario. – ildjarn

+1

Ah, questa è la prima volta che uso MPL, chi sapeva che poteva essere così contorto? – grivescorbett