unordered_map of std::ofstream

unordered_map of std::ofstream

本文关键字:ofstream std of map unordered      更新时间:2023-10-16

我想使用std::unordered_map<unsigned,std::ofstream>但失败了。现在我想知道这是否根本不可能,或者编译器问题,或者我只是没有做对。问题是插入了另一个元素:

std::ofstream&get(unsigned key, std::unordered_map<unsigned,std::ofstream>&map)
{
  auto file = map.find(key);
  if(file==map.end()) {
    map.emplace(std::make_pair(key,std::ofstream{}));  // <-- trouble here
    file = map.find(key);
    assert(file!=map.end());
  }
  return file->second;
}

使用 GCC (4.8.1) 失败,因为std::ofstream不可复制构造。

但是,它是可移动构造的,所以应该有一个解决方案,还是没有?(我只想插入一个默认构造的std::ofstream)。我试图添加有些std::move(),但这没有帮助。

我刚刚注意到上面的代码确实使用 clang 3.4 编译。这不是错吗?

你先做一对,然后要求map再次构造这对并导致问题

尝试

map.emplace(key,std::ofstream{});

实际上,您所需要的只是

std::ofstream&get(unsigned key, std::unordered_map<unsigned,std::ofstream>&map)
{
  return map[key];
}

或删除此功能...并使用map[key]

因为如果使用不存在的键,map 将使用默认构造函数构造ofstream,所以它应该像你的代码一样工作

它与 GCC 编译器无关,也可能与所有其他编译器无关,basic_fstream提供了相当简单的操作,在此文件流之上没有复制操作。解决方案是,如果您希望两个名称引用同一个文件流,请使用引用或指针或操作文件流。

STL经常使用copy,上面用emplacemake_pair使用copy。insert()更方便的符号.这m[k]的结果等价于(*(<map>.insert(make_pair(k,V{})).first)).second的结果,其中V是映射的类型,所以那里没有移动。

移动和复制的细微区别是,复制后两个对象必须具有相同的值,而在移动后,源移动不需要具有其原始值。可以使用移动当源对象不再使用时。他们特别对于实现移动资源的概念很有用。对于最有趣的情况,容器(移自状态)为"空"。

复制

或移动对象有五种情况:• 作为作业的来源• 作为对象初始化器• 作为函数参数• 作为函数返回值• 作为例外在所有情况下,都将应用复制或移动构造函数(除非它可以优化)。

估计在当前标准中适应这一点的机会微乎其微,这还没有结束前面提到的,在你的情况下,你能不能使用指向 ofstream 的指针?

unordered_map<int, ofstream*> map1;
map1.emplace(1, new ofstream());

您对其他使用 move 的编译器有任何想法吗?