2012-05-24 42 views
7

Vì vậy, tôi có một lớp mẫu mà tôi muốn chấp nhận một std :: map nơi kiểu dữ liệu hoặc là một con trỏ thô hoặc một std :: unique_ptr. Sau đó, trong lớp này, tôi muốn để có được các loại con trỏ cơ bản:Đánh giá lập trình meta mẫu

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 

Tuy nhiên tôi nhận được lỗi sau khi instantiating lớp sử dụng một bản đồ với một kiểu con trỏ liệu:

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

Nó dường như với tôi như nó đang đánh giá typename Container::mapped_type::element_type* trên con trỏ thô, tôi nghĩ rằng với mẫu lập trình meta nó sẽ không đánh giá rằng khi if_ đã thành công. Tôi có nên đi về điều này theo một cách khác không?

Trả lời

11

Bạn cần một lười biếngif – thử boost::mpl::eval_if thay vì 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; 
}; 

Tức là, khi nghi ngờ, thêm thêm một lớp về mình.

+1

Cảm ơn! Điều đó làm việc, sử dụng lười biếng nếu có ý nghĩa nhưng tôi không thực sự hiểu tại sao bạn cần danh tính và extract_element_type ? – grivescorbett

+1

@grivescorbett: Thay vì các loại trực tiếp như 'if_',' eval_if' lấy các metafunctions unary mà _produce_ type. Đó là đánh giá lười biếng/instantiation của metafunctions nói là những gì làm cho nó hoạt động theo cách bạn cần. – ildjarn

+1

Ahh, đây là lần đầu tiên tôi sử dụng MPL, ai biết nó có thể phức tạp như vậy? – grivescorbett

Các vấn đề liên quan