从任意Map获取指向mapped_type的指针或引用

Getting Pointer or Reference to mapped_type from Arbitrary Map

本文关键字:type 指针 引用 mapped Map 任意 获取 取指      更新时间:2023-10-16

编辑:我已经找到并写了一个解决我的问题的方法,但我没有回答这个问题,因为我的解决方案可能仍然不理想。

我正在编写一个小库,旨在执行地图的地图例程,但我在设计一组类模板时遇到了麻烦,这些模板将让我获得一个指针或引用(取决于地图的value_type的second_type)到地图的mapped_type,而不管地图的类型(例如std::map, boost::ptr_map)。

为了进一步说明,我列出了一些输入类型和期望的输出类型。

Case   Input Type                                   Output Type
 A     std::map<int, std::map<int, int> >           std::map<int, int>&
 B     std::map<int, boost::ptr_map<int, int> >     boost::ptr_map<int, int>&
 C     boost::ptr_map<int, std::map<int, int> >     std::map<int, int>* const
 D     std::map<int, std::map<int, int> >*          std::map<int, int>&
 E     std::map<int, boost::ptr_map<int, int> >*    boost::ptr_map<int, int>&
 F     boost::ptr_map<int, std::map<int, int> >*    std::map<int, int>* const

我的代码通过了情况A、B、D和E,但在情况C和f上失败了。

template <class Map>
struct map_utils
{
    template <class K>
    static typename
    boost::remove_pointer<
            typename Map::value_type
    >::type::second_type&
    get(Map& m, const K k)
    {
            return m[k];
    }
    template <class K>
    static typename
    boost::remove_pointer<
            typename Map::value_type
    >::type::second_type&
    get(const Map& m, const K k)
    {
            return const_cast<Map&>(m)[k];
    }
};
template <class Map>
struct map_utils<Map*>
{
    template <class T>
    static typename
    boost::remove_pointer<
            typename Map::value_type
    >::type::second_type&
    get(Map* m, const T t)
    {
            return (*m)[t];
    }
    template <class T>
    static typename
    boost::remove_pointer<
            typename Map::value_type
    >::type::second_type&
    get(const Map* m, const T t)
    {
            return const_cast<Map*>(m)->operator[](t);
    }
};

我试图使用boost::mpl来做到这一点,这就是我到目前为止所做的,但是我使用两个版本的代码得到相同的错误。

错误。

error: invalid initialization of reference of type ‘std::map<int, double>* const&’ from         expression of type     ‘boost::ptr_container_detail::reversible_ptr_container<boost::ptr_container_detail::map_config<std::map<int, double>, std::map<int, void*, std::less<int>, std::allocator<std::pair<const int, void*> > >, true>, boost::heap_clone_allocator>::Ty_’

结构体的修改专门化,以处理非映射指针的l值。

template <class K>
    static typename
    boost::mpl::if_<
            boost::is_pointer<
                    typename boost::remove_pointer<
                            typename Map::value_type
                    >::type::second_type
            >,
            typename boost::remove_pointer<
                    typename boost::remove_const<
                            typename Map::value_type
                    >::type
            >::type::second_type,
            typename boost::remove_pointer<
                    typename Map::value_type
            >::type::second_type&
    >::type
    get(Map& m, const K k)
    {
            return m[k];
    }

C和F似乎是错误的,映射类型不是boost::ptr_map。否则,听起来您可以使用完整的模板专门化来确定它是std::map还是boost::ptr_map。像这样:

template <class Map>
class Whatever;
template <class K, class V>
class Whatever<std::map<K, V> >
{
    public:
        typedef V& Type;
};
template <class K, class V>
class Whatever<std::map<K, V>* >
{
    public:
        typedef V& Type;
};
template <class K, class V>
class Whatever<boost::ptr_map<K, V> >
{
    public:
        typedef V* const Type;
};
template <class K, class V>
class Whatever<boost::ptr_map<K, V>* >
{
    public:
        typedef V* const Type;
};

我已经得到了代码编译成功,并大大简化了它在这个过程中,通过使用mapped_type类型定义,像这样:

template <class K>
static typename boost::remove_pointer<
        typename Map::mapped_type
>::type&
get(Map& m, const K k)
{
        return m[k];
}

在上面问题中定义的结构体的专用版本中,只有方法体需要更改,以便也适应指向映射的指针。如果您想要完整的代码清单,请告诉我,我会将整个代码转储到这里。