net*_*eff 239
当你写作
map[key] = value;
Run Code Online (Sandbox Code Playgroud)
没有办法告诉你是否更换了valuefor key,或者你是否创建了一个新key的value.
map::insert() 只会创建:
using std::cout; using std::endl;
typedef std::map<int, std::string> MyMap;
MyMap map;
// ...
std::pair<MyMap::iterator, bool> res = map.insert(MyMap::value_type(key,value));
if ( ! res.second ) {
cout << "key " << key << " already exists "
<< " with value " << (res.first)->second << endl;
} else {
cout << "created key " << key << " with value " << value << endl;
}
Run Code Online (Sandbox Code Playgroud)
对于我的大多数应用程序,我通常不关心我是否正在创建或替换,因此我使用更容易阅读map[key] = value.
Gre*_*ers 53
当涉及到地图中已存在的密钥时,这两者具有不同的语义.所以它们并不是真正可比的.
但是operator []版本需要默认构造值,然后分配,所以如果这更昂贵然后复制构造,那么它将更昂贵.有时默认构造没有意义,然后就不可能使用operator []版本.
Haw*_*ker 34
另外需要注意的是std::map:
myMap[nonExistingKey];将在地图中创建一个新条目,键入nonExistingKey初始化为默认值.
当我第一次看到它时,这让我感到很害怕(同时我的头撞在了一个非常遗留的小虫身上).不会期待它.对我来说,这看起来像一个获取操作,我没想到"副作用".不想map.find()从你的地图时获得.
Tor*_*ack 19
如果默认构造函数的性能不是问题,那么对于上帝的爱,请使用更易读的版本.
:)
ant*_*_rh 14
insert 从异常安全的角度来看更好.
表达式map[key] = value实际上是两个操作:
map[key] - 使用默认值创建地图元素.= value - 将值复制到该元素中.第二步可能会发生异常.结果,操作将仅部分完成(在元素中添加了一个新元素,但该元素未初始化value).操作未完成但系统状态被修改的情况称为具有"副作用"的操作.
insert操作提供了强有力的保证,意味着它没有副作用(https://en.wikipedia.org/wiki/Exception_safety).insert要么已完全完成,要么将地图保留为未修改状态.
http://www.cplusplus.com/reference/map/map/insert/:
如果要插入单个元素,则在异常情况下容器中没有更改(强保证).
Ram*_*ary 13
如果您的应用程序速度很快,我将建议使用[]运算符,因为它创建了原始对象的总共3个副本,其中2个是临时对象,并且迟早会被销毁.
但是在insert()中,创建了4个原始对象的副本,其中3个是临时对象(不一定是"临时对象")并被销毁.
这意味着额外的时间:1.一个对象内存分配2.一个额外的构造函数调用3.一个额外的析构函数调用4.一个对象内存释放
如果你的对象很大,构造函数是典型的,析构函数可以释放大量的资源,上面的点数更多.关于可读性,我认为两者都是公平的.
同样的问题进入我的脑海,但不是可读性而是速度.这是一个示例代码,通过它我了解了我提到的这一点.
class Sample
{
static int _noOfObjects;
int _objectNo;
public:
Sample() :
_objectNo( _noOfObjects++ )
{
std::cout<<"Inside default constructor of object "<<_objectNo<<std::endl;
}
Sample( const Sample& sample) :
_objectNo( _noOfObjects++ )
{
std::cout<<"Inside copy constructor of object "<<_objectNo<<std::endl;
}
~Sample()
{
std::cout<<"Destroying object "<<_objectNo<<std::endl;
}
};
int Sample::_noOfObjects = 0;
int main(int argc, char* argv[])
{
Sample sample;
std::map<int,Sample> map;
map.insert( std::make_pair<int,Sample>( 1, sample) );
//map[1] = sample;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
![使用[]运算符时的输出](https://i.stack.imgur.com/oVUVV.png)
Gut*_*Mac 10
现在在c ++ 11中我认为在STL映射中插入一对的最佳方法是:
typedef std::map<int, std::string> MyMap;
MyMap map;
auto& result = map.emplace(3,"Hello");
Run Code Online (Sandbox Code Playgroud)
该结果将是具有一对:
第一个元素(result.first)指向插入的对,或者如果该键已存在则指向该键.
第二个元素(result.second),如果插入正确或为假,则出现错误.
PS:如果您不了解订单,可以使用std :: unordered_map;)
谢谢!
map :: insert()的问题在于,如果密钥已经存在于地图中,它将不会替换值.我见过Java程序员编写的C++代码,他们希望insert()的行为与Java中的Map.put()相同,其中值被替换.
| 归档时间: |
|
| 查看次数: |
158846 次 |
| 最近记录: |