编辑:我找到了并解决了我的问题,但由于我的解决方案可能仍然不理想,因此我没有回答这个问题。
我正在编写一个小型库,用于在地图地图上执行例程,但是我在设计一组类模板时遇到问题,这些模板将让我获得指针或引用(取决于map的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];
}
答案 0 :(得分:1)
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;
};
答案 1 :(得分:0)
通过使用mapped_type typedef,我已经成功编译了代码,并在此过程中大大简化了代码:
template <class K>
static typename boost::remove_pointer<
typename Map::mapped_type
>::type&
get(Map& m, const K k)
{
return m[k];
}
只有方法体才需要在上面问题中定义的结构的专用版本中进行更改,以便适应指向地图的指针。如果你想要整个代码清单,请告诉我,我会在这里抛弃整个代码。