7

したがって、データ型がrawポインターまたは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_が成功したときにそれを評価しないと思いました。これについては別の方法で行う必要がありますか?

4

1 に答える 1

11

怠惰な ものが必要です–代わりにif試してください:boost::mpl::eval_ifboost::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;
};

つまり、疑わしい場合は、間接参照のレイヤーを追加します。

于 2012-05-24T23:48:01.733 に答える