在std::unordered_map中分配ID后创建对象

Create object after ID is allocated in std::unordered_map

本文关键字:分配 ID 创建对象 map std unordered      更新时间:2023-10-16

我有一个std::unordered_map,它存储一个带有对象的整数。这里有一些代码供您理解:

#include <iostream>
#include <unordered_map>
#include <cstdlib>
using namespace std;
class Foo
{
public:
    Foo()
    {
        cout << "Foo created!" << endl;
    }
    ~Foo()
    {
    }
};
typedef std::unordered_map<int, Foo*> FooMap;
FooMap fm;
int allocateID()
{
    cout << "Allocating ID" << endl;
    return rand() % 100;
}
void add()
{
    fm.emplace(allocateID(), new Foo());
}
int main()
{
    srand(time(NULL));
    add();
    return 0;
}

输出:

Foo created!
Allocating ID

这里的问题是对象Foo是在分配ID之前创建的!我尝试在allocateID上添加一个互斥锁;它不起作用,因为allocateID()在对象创建后运行

如何修改此程序,以便在分配ID后创建Foo

编辑:

我已经玩过这些代码,并在这里使用了一个解决方案来演示:

void add(int id, Foo *f)
{
    auto iden = id;
    auto foo = f;
    fm[iden] = foo;
}
void add(Foo *f, int id)
{
    auto iden = id;
    auto foo = f;
    fm[iden] = foo;
}
void add()
{
    int id = allocateID();
    fm[id] = new Foo();
}

在第一个add()函数中,输出保持不变。这并不能解决问题。

在第二个add()函数中,输出不同,而是产生:

Allocating ID
Foo created!

在第三个函数中,它已经用其中一个解决方案进行了修改:这个函数也会产生所需的输出。第三个函数的问题是,实际上不太可能有一个空的add()函数。解决此问题的唯一应受谴责的方法是先传递对象,然后传递id。这可能是因为参数是从右到左读取的,而不管输入要求如何,因为它们是在读取参数之后创建的。

不能依赖函数参数的求值顺序。试试这个:

void add()
{
    int temp = allocateID();
    fm.emplace(temp, new Foo());
}

除非你完全确定编译器将如何解释你的代码,否则你不想依赖它并让它告诉你想要做什么。既然你有问题,你应该强制编译器首先创建id,如下所示:

void add()
{
    int id = allocateID();
    fm[id] = new Foo();
}

这将解决您的问题。