我正面临一个问题。返回std::pair<T1,>来自lambda函数。我试图生成地图与打开ifstream的,但编译器抱怨与此输出:
/usr/include/c++/9/bits/stl_algo.h:4337:12:错误:使用已删除函数' std::pair
&Std::pair ::operator=(const Std::pair &) '
我检查了std::pair的cppref,我没有注意到复制操作符=对于这个是不可行的。
我相当肯定lambda返回对是可能的,那么在下面的代码段中我肯定有一些误解。
std::map<int, std::string> mFileMap;
std::map<std::string, std::ifstream> files;
std::transform(mFileMap.begin(), mFileMap.end(), files.begin(),
[](const auto& arg) -> std::pair<std::string, std::ifstream> {
std::string path(arg.second);
std::ifstream stream(path);
return std::make_pair(path, stream);
});
std::pair
是可复制的,只要std::pair
中的内容是可复制的。如果你想一下,几秒钟,你会同意这是100%有道理的。
std::pair<std::string, std::ifstream>
std::ifstream
不可复制。不能复制std::ifstream
s。把它放在std::pair
中并不能使它成为可复制的。
但这不是所示代码中最不重要的问题:
std::map<std::string, std::ifstream> files;
std::transform(mFileMap.begin(), mFileMap.end(), files.begin(),
// ...
files
映射为空。files.begin()
将开始迭代器返回一个空映射,该映射的值与files.end()
相同。试图复制到结束迭代器(忽略底层类型不可复制的事实)将不会有好的结果。
此外,std::map
的键在映射中是恒定的,所以这也不起作用。
这不是如何添加到地图的东西,需要使用std::insert_iterator
。
因此,总结起来,必须解决以下问题:
- 此
std::pair
不可复制。 - 必须使用
std::insert_iterator
向std::map
插入新的键/值对。
假设你坚持你的std::map
包含这些值,你将不得不做一些工作来填充它,使用std::map::emplace
,这将是最实用的方法来添加新的东西到这个地图。
多亏了Sam,我找到了解决这个问题的方法。因此,一个可能的修复方法是
std::map<std::string, std::ifstream> files;
std::transform(mFileMap.begin(), mFileMap.end(), std::inserter(files, files.end()),
[](auto const& arg) -> std::pair<std::string, std::ifstream> {
std::string path(arg.second);
return std::make_pair(path, std::ifstream(path));
});