![](/img/trans.png)
[英]How do I insert a element into a std::unordered_map<int, vector<Object*>>
[英]when std::map::insert finds the element, it still constructs an instance of the object. How can I stop this?
我有一个对象的std :: map,其实例的构造非常昂贵。 (在现实生活中,它们需要对数据库的多次访问。)
我想访问地图的某个元素,或者如果不存在则创建它。 这听起来像std :: map :: insert的工作,只是不必要地构造了昂贵的对象,然后在元素存在的情况下将其丢弃。 为了显示:
#include <iostream>
#include <map>
#include <string>
struct CexpensiveObject
{
CexpensiveObject(const char* args="default"):args_(args)
{
std::cout << "Constructor: CexpensiveObject(" << args << ")" << std::endl;
}
CexpensiveObject( const CexpensiveObject& other )
{
std::cout << "Copy Constructor: CexpensiveObject other.args_ = " << other.args_ << "." << std::endl;
args_ = other.args_;
}
~CexpensiveObject()
{
std::cout << "Destructor: CexpensiveObject args_ = " << args_ << "." << std::endl;
}
const char* args_;
};
// entry point
int main()
{
typedef std::map<std::string, CexpensiveObject> mymaptype;
mymaptype mymap;
std::pair<mymaptype::iterator, bool> insertionResult;
std::cout << "First insertion" << std::endl;
insertionResult = mymap.insert( mymaptype::value_type( "foobar", CexpensiveObject("first") ) );
std::cout << "Was it inserted? " << (insertionResult.second?"yes":"no") << std::endl;
std::cout << "Second insertion" << std::endl;
insertionResult = mymap.insert( mymaptype::value_type("foobar", CexpensiveObject("second") ) );
std::cout << "Was it inserted? " << (insertionResult.second?"yes":"no") << std::endl;
}
结果:
First insertion
Constructor: CexpensiveObject(first)
Copy Constructor: CexpensiveObject other.args_ = first.
Copy Constructor: CexpensiveObject other.args_ = first.
Destructor: CexpensiveObject args_ = first.
Destructor: CexpensiveObject args_ = first.
Was it inserted? yes
Second insertion
Constructor: CexpensiveObject(second)
Copy Constructor: CexpensiveObject other.args_ = second.
Destructor: CexpensiveObject args_ = second.
Destructor: CexpensiveObject args_ = second.
Was it inserted? no
Destructor: CexpensiveObject args_ = first.
复制和销毁比我预期的要多,但是关键是要构造一个实例CexpensiveObject,然后如果在ma中存在具有相同键的元素,则将其丢弃。
我是在滥用std :: map :: insert还是必须在实例化CexpensiveObject实例之前使用std :: map :: find检查具有相同键的元素是否存在?
它是在调用CexpensiveObject("second")
甚至insert
之前构造的。 您正在传递无关的对象! (然后在将value_type
传递给insert
其复制。)
代替insert
,使用find
。 如果您在所需的键处找到该项目,那么您就完成了。 如果不是, 则将其插入。
auto it = mymap.find("foobar");
if (it == mymap.end())
mymap.insert(mymaptype::value_type("foobar", CexpensiveObject("second")));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.