C++ 强制std::map的键类型不为常量
C++引用告诉我们一个std::mapC++ 强制std::map的键类型不为常量,c++,stl,map,C++,Stl,Map,C++引用告诉我们一个std::map typedef pair<const Key, T> value_type; typedef对值\u类型; 是否可以强制密钥类型不为常量? 我需要在模板方法中这样做 template<class T> // T represent a map in general (std::map, boost::unordered_map or whatever..) void foo(const T& m) { typenam
typedef pair<const Key, T> value_type;
typedef对值\u类型;
是否可以强制密钥类型不为常量?
我需要在模板方法中这样做
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 ...
}
template//T通常表示一个映射(std::map、boost::unordered\u map或其他任何..)
void foo(施工测试与维护)
{
typename T::value\u type::first\u type x;
x=0;//错误,因为x是常量。。。
}
不,不是
这是因为map基于键执行其内部排序。如果你能自己修改钥匙,不管你愿不愿意,所有的麻烦都会爆发
您应该使用提供的API函数;如果使用一个键导致更改键值(实际上我不认为任何键值会更改),则可能会进行适当的内部重新排序
想想getter和setter,以及它们在提供混乱/危险的直接成员访问的替代方法中的使用
但是,您可以这样写:
template<class T>
void foo(const T& m)
{
typename T::key_type x;
x = 0;
}
typename T::key\u type
将为您提供密钥类型,而无需添加const
限定符。前面的答案应该足以回答您的简单问题。作为一种更通用的方法,您可以使用(来自boosttype_traits)删除类型的常量限定符
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;
}
template//T通常表示一个映射(std::map、boost::unordered\u map或其他任何..)
void foo(施工测试与维护)
{
typedef typename T::value_type::first_type X;//是常量
typedef typename boost::remove_const::type NonConstX;
非stx;
x=0;
}
密钥类型必须为常量。如果您确定不会更改映射的顺序,则可以丢弃迭代器的常量。如果您弄错了,这可能会导致丑陋的错误。有关信息,Boost.MultiIndex提供了update
方法,允许您更改给定对象(就地),然后在所有索引中正确地重新定位它。显然,这比STL-map/unordered_-map高级得多:)抱歉,Dennis,如果您使用map按对象成员对实例化对象进行排序,那么这样做是非常有效的。如果您不更改该成员,则表示您没有更改订单。一个完全不可变的容器不是一个非常有用的工具。地图存储成对的对象。请注意,密钥存储在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;
}