我想使用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编译的。这不对吗?
答案 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经常使用副本,上面的emplace
或make_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}}
你对其他与移动有关的编译器有什么想法吗?