C++ 指定给地图时构造的两个对象

C++ 指定给地图时构造的两个对象,c++,arrays,pointers,C++,Arrays,Pointers,我试图在我的地图中存储对象,但显然,当我尝试分配一个新对象时,它们会被构造两次,一个立即被破坏。 有没有一种方法可以在地图中创建本地对象,或者我必须存储指针 std::map<std::wstring,Bitmap> bitmaps; void loadBitmaps(){ for(auto f: listdir("bitmaps")) { std::wcout << "loading: " << f << std::end

我试图在我的地图中存储对象,但显然,当我尝试分配一个新对象时,它们会被构造两次,一个立即被破坏。 有没有一种方法可以在地图中创建本地对象,或者我必须存储指针

std::map<std::wstring,Bitmap> bitmaps;
void loadBitmaps(){
    for(auto f: listdir("bitmaps")) {
        std::wcout << "loading: " << f << std::endl;
        bitmaps[f] = Bitmap(f);
        std::wcout << "loaded\n";
    }
}
std::map操作符[](键)`是特殊的:

  • 如果键存在,则返回对映射值的引用
  • 否则,将插入具有默认构造映射类型的新对,并返回对新映射值的引用
其他标准容器不具有此行为


您观察到插入了一个新的默认构造映射值,但在日志输出中错过了赋值(也分析运算符=(…)。

首先,映射是空的。调用
位图[f]
时,将创建键
f
的条目和默认构造值。这是您看到的
空构造函数。因此,在这种情况下:

  • 位图的(临时)实例是通过
    Bitmap(f)
  • 默认构造的位图是通过
    位图[f]
  • 临时位图通过
    Bitmap&Bitmap::operator=(Bitmap&)
    Bitmap&Bitmap::operator=(Bitmap&)
    分配给默认构造的位图,具体取决于位图的实现

  • 我建议使用
    位图。请改用emplace(f,f)

    您的示例没有使用数组,而是使用
    std::map
    std::map::operator[]
    default构造一个对象(如果该键上还没有对象)。要在位构造对象,请使用


    你想实现一个移动分配操作符。顺便说一句,这不是一个数组。在引擎盖下,它通常是一个树,而不是一个数组。另外,一种补充移动赋值操作符的方法是使用
    map::emplace()
    ::。我不知道为什么,但我得到了这个错误:“const std::pieclewise_construct”不是从“const std::pair”派生出来的。我已经检查了其他方法,通过向键和值添加std::forward_as_tuple(f)解决了这个问题
    loading: bitmap1.bmp
    created with file constructor
    created with empty constructor
    destructed (the one with the file constructor)
    loaded
    
    bitmaps.emplace(std::piecewise_construct, f, f);