【发布时间】:2019-11-20 02:51:43
【问题描述】:
我有一个map 类型为<int, foo*>,我是从数据库中填充的。 int 是一个唯一键,所以在填充之前,我会检查键是否已经在映射中,如果不是 foo 类型的新对象被创建并插入到映射中。
foo 类还有另一个映射作为属性,类型为<int, float>,也需要从数据库中填充。我有下面的代码,据说很简单:
std::map<int, foo> MAP;
while(getline(infile, line))
{ //reading records in data file
string item;
stringstream ss(line);
vector<string> splittedString;
int a = stoi(splittedString[0]); // cells after splitting data
int b = stoi(splittedString[1]);
float c = stof(splittedString[2]);
if (MAP.find(a) == MAP.end())
{
foo f = foo();
MAP.insert({a, &f});
f.fooMap.insert({b, c/100});
}
else
{
foo* f = MAP.at(a);
f->fooMap.insert({b, c/100});
}
}
计算需要花费大量时间。大约有 50,000 条记录,但这不应该永远持续下去。我很确定我做错了什么,因为我对 c++ 有点生疏了。
我知道在创建 foo 对象时我有一些冗余,我认为执行上述操作的更有效方法是下面的“不正确”代码:
while(getline(infile, line))
{//reading records in data file
string item;
stringstream ss(line);
vector<string> splittedString;
int a = stoi(splittedString[0]); //cells after splitting data
int b = stoi(splittedString[1]);
float c = stof(splittedString[2]);
foo f = *MAP[a];
if (f == NULL)
{
f = foo();
MAP.insert({a, &f});
}
f->fooMap.insert({b, c/100});
}
更新
如果我使用MAP<int, foo> 而不是MAP<int, foo*>(并相应地安排插入代码),则代码可以正常工作。所以我用指针做错了。解决这个问题的最佳方法是什么?
【问题讨论】:
-
你知道
MAP({a, &f});是做什么的吗?为什么?MAP是什么? -
个人资料?拆分和计算 c 的成本是多少?您可以只使用
insert()该值,它会返回一个布尔值,告诉您它是否已经存在。您也可以使用emplace()在插入之前不构造值,但这在 c++11 中很难有效使用。在 c++17 中使用try_emplace(),但是如果你想节省计算 c 和 foo() 的工作量,你需要发明一个可以分别由 splittedString[2] 或 foo() 构造的包装类。跨度> -
不要使用
<int, foo*>。而是使用<int, std::unique_ptr<foo>>。 -
@user7331538,我怀疑
MAP({a, &f});或MAP(a)是有效的语法。 -
请再次查看
std::map界面。没有为std::map定义呼叫运算符 (operator())。因此,您的MAP(a)要么是错误的,要么它没有按照您的预期执行...
标签: c++ dictionary object pointers insert