我在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字符串和字符串之间是否有转换?
答案 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);
这只会让您的代码看起来更清晰,为什么不利用已经存在的功能?