繁体   English   中英

std :: ofstream的unordered_map

[英]unordered_map of std::ofstream

我想使用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.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的其他编译器有任何想法吗?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM