c ++ map中的元素类型

时间:2015-09-11 22:33:22

标签: c++ dictionary types stl

我在this讲座中听说过有关C ++关联容器的内容,如果您有以下地图:

map<string,string> m;

其元素类型为:

pair<const string,string>

我有一个代表电话号码列表的小班

PhoneList operator+(const PhoneList & g){
      PhoneList copy(*this);
      for(map<string,string>::const_iterator it = g.datos.begin(); it != g.datos.end(); ++it){
        copy.insert(*it);
      }
      return copy;
}

问题是insert方法有以下标题:

 pair<map<string,string>::iterator,bool>  insert(pair<string,string> p)
显然我正在将一对转换成一对。

我想知道为什么会这样。 const字符串和字符串之间是否有转换?

2 个答案:

答案 0 :(得分:2)

您的代码有两个原因。首先,因为您按值传递了insert()&#39的参数:

pair<map<string,string>::iterator,bool>  insert(pair<string,string> p)

如果您通过引用传递参数,那么您的代码将无法编译:

pair<map<string,string>::iterator,bool>  insert(const pair<string,string> &p)

按值传递非平凡参数通常效率较低,但由于此处您按值传递此参数,因此参数基本上是复制构造的。这是第二个原因。您最终使用以下std::pair模板构造函数:

template<class U, class V> pair(const pair<U, V>& p);

Requires: is_constructible<first_type, const U&>::value is true and
is_constructible<second_type, const V&>::value is true.

Effects: Initializes members from the corresponding members of the
argument.

这就是为什么你能够编译你的代码。总而言之,这个模板构造函数允许std::pair<A, B>std::pair<C, D>,不同的类构造,如果A可以用C构造,B可以用D构造。在你的情况A,B和D中是std::string,C是const std::string。从其他std::string构建新的std::string显然不是问题,它是一个普通的复制构造函数。

答案 1 :(得分:-1)

元素属于

的原因
pair<const string,string>

是禁止您更改地图中的密钥。将键值对插入映射时,该键用于选择键值对应在内部数据结构中的位置。 STL只是不允许您更改密钥,因为它必须删除该元素并使用不同的密钥重新插入它。当然他们可以做到这一点,但他们没有。您可以根据需要更改所有值,但密钥将保持与原始密钥相同。如果您需要复制值,使用新密钥和复制的值创建新的键值对,则可以自己执行此操作,然后删除旧的键值对。

此外,您可以使用基于范围的插入来简化代码。

template <class InputIterator>
void insert (InputIterator first, InputIterator last);

这只会让您的代码看起来更清晰,为什么不利用已经存在的功能?

参考文献: http://www.cplusplus.com/reference/map/map/insert/