2012-05-24 7 views
7

私は、データ型が生ポインタまたはstd :: unique_ptrのいずれかであるstd :: mapを受け入れるテンプレートクラスを持っています。生のポインタ型にマップを使用してクラスをインスタンス化する際に、私は次のエラーを取得するしかしテンプレートメタプログラミング評価

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_が成功したときにそれを評価しないと思っていました。私はこれとは別の方法で行くべきですか?あなたが怠惰なif –が必要

答えて

11

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; 
}; 

すなわち、疑問で、間接の余分なレイヤを追加します。

+1

ありがとうございます!それはうまくいけば怠け者を使ってもうまくいきましたが、私は本当にIDが必要な理由を理解していませんとextract_element_type ? – grivescorbett

+1

@grivescorbett:直接 'if_'のような型ではなく、' eval_if'は_produce_型の単項メタ関数をとります。このメタ関数の怠惰な評価/インスタンス化は、あなたが必要とするように動作させるものです。 – ildjarn

+1

ああ、MPLを使ったのはこれが初めてのことです。 – grivescorbett