C++ 模板元编程评估

C++ 模板元编程评估,c++,boost,template-meta-programming,boost-mpl,C++,Boost,Template Meta Programming,Boost Mpl,所以我有一个模板类,我想接受一个std::map,其中的数据类型要么是原始指针,要么是std::unique\u ptr。然后在这个类中,我想得到底层指针的类型: typedef typename boost::mpl::if_< boost::is_pointer<typename Container::mapped_type>, typename Container::mapped_type, typename Container::mapped_t

所以我有一个模板类,我想接受一个std::map,其中的数据类型要么是原始指针,要么是std::unique\u 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
typedef typename boost::mpl::if_<
boost::是_指针,
typename容器::映射的\u类型,
typename容器::映射的类型::元素类型*
>::类型数据类型
但是,当使用具有原始指针类型的映射实例化该类时,会出现以下错误:

error: 'std::map<int, ValueType*>::mapped_type {aka ValueType*}' is not a class, struct, or union type
错误:“std::map::mapped_type{aka ValueType*}”不是类、结构或联合类型
在我看来,它就像是在原始指针上计算
typename Container::mapped\u type::element\u type*
,我认为使用模板元编程时,如果成功,它将不会计算该值。我应该换一种方式吗?

你需要一个懒惰的
if
——尝试
boost::mpl::eval\u 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;
};
#包括
#包括
#包括
模板
结构提取元素类型
{
typedef typename T::element_type*type;
};
模板
结构foo
{
typedef typename boost::mpl::eval_if<
boost::是_指针,
boost::mpl::identity,
提取元素类型
>::类型数据类型;
};

也就是说,如果有疑问,请添加额外的间接层。

谢谢!这是可行的,使用惰性if是有道理的,但我真的不明白为什么需要标识和提取元素类型?@grivescorbett:
eval\u if
而不是直接像
if
这样的类型,它采用生成类型的一元元函数。对所述元函数的延迟求值/实例化正是使其按您需要的方式工作的原因。啊,这是我第一次使用MPL,谁知道它会如此复杂?@grivescorbett it变得更糟!:P