强制std::map的键类型不能为const

force key type of a std::map not to be const

本文关键字:不能 类型 const std map 强制      更新时间:2023-10-16

c++参考告诉我们std::map

typedef pair<const Key, T> value_type;

是否可以强制键类型不为const ?我需要在模板方法中这样做,比如

template<class T> // T represent a map in general (std::map, boost::unordered_map or whatever..)
void foo(const T& m)
{
  typename T::value_type::first_type x;
  x=0; // Wrong because x is const ...
}

不,它不是。

这是因为map根据键执行内部排序。如果你能自己修改钥匙,不管你愿不愿意,一切都会乱成一团。

你应该使用提供的API函数;如果使用一个导致改变一个Key值(实际上我不认为有任何改变),则可能发生适当的内部重新排序。

考虑getter和setter,以及它们在提供混乱/危险的直接成员访问的替代方法中的用途。


但是,你可以这样写:

template<class T>
void foo(const T& m)
{
   typename T::key_type x;
   x = 0;
}

std::map类型别名

key_type                Key
mapped_type             T
value_type              pair<const Key,T>
key_compare             Compare
value_compare           Nested class to compare elements
allocator_type          Allocator
reference               Allocator::reference
const_reference         Allocator::const_reference
iterator                Bidirectional iterator
const_iterator          Constant bidirectional iterator
size_type               Unsigned integral type (usually same as size_t)
difference_type         Signed integral type (usually same as ptrdiff_t)
pointer                 Allocator::pointer
const_pointer           Allocator::const_pointer
reverse_iterator        reverse_iterator<iterator>
const_reverse_iterator  reverse_iterator<const_iterator>

typename T::key_type将为您提供键类型,而无需添加const限定符。

前面的答案应该足以回答你的简单问题。作为一种更通用的方法,您可以使用boost::remove_const(来自boost type_traits)来移除类型的const限定符。

template<class T> // T represent a map in general (std::map, boost::unordered_map or whatever..)
void foo(const T& m)
{
  typedef typename T::value_type::first_type X; //is const
  typedef typename boost::remove_const<X>::type NonConstX;
  NonConstX x;
  x=0; 
}

键类型必须为const。如果确定不会改变映射的顺序,则可以抛弃迭代器的const-ness。如果你弄错了,这可能会导致丑陋的bug。

相关文章: