std :: ofstream的unordered_map

时间:2014-04-04 12:59:56

标签: c++ c++11 move-semantics unordered-map

我想使用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编译的。这不对吗?

2 个答案:

答案 0 :(得分:3)

你先做一对,然后再问地图再造一对并导致问题

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

实际上,你需要的只是

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

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

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

答案 1 :(得分:0)

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

STL经常使用副本,上面的emplacemake_pair使用副本 insert()更方便的表示法。该 m[k]的结果等同于(*(<map>.insert(make_pair(k,V{})).first)).second的结果,其中V是映射的。unordered_map<int, ofstream*> map1; map1.emplace(1, new ofstream()); 类型,所以那里没有动作。

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

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

认为在现行标准中存在黯淡的机会,但尚未结束 在你的情况下,你可以不使用指向ofstream的指针吗?比如

{{1}}

你对其他与移动有关的编译器有什么想法吗?