Rom*_*huk 1 c++ stdmap stdvector
我有std::vector<std::map<int, std::unique_ptr<int>>>容器(如果为了简化)。最初,我必须插入std::vector一定数量的std::map,每个都有一个键值对。我尝试过这样的代码:
#include <iostream>
#include <map>
#include <vector>
#include <memory>
using namespace std;
int main()
{
vector<map<int, std::unique_ptr<int>>> data{};
for (int x = 0; x < 10; x++)
{
data.emplace_back(std::make_pair(x, std::make_unique<int>(x)));
}
}
Run Code Online (Sandbox Code Playgroud)
但这没有用。我怎样才能改变它以使其按预期工作?
编辑:我明白我的错误,我必须使用这段代码来添加元素:
std::map<int, std::unique_ptr<int>> m;
m.emplace(x, std::make_unique<int>(y));
data.emplace_back(std::move(m));
Run Code Online (Sandbox Code Playgroud)
然后,该代码可以在在线编译器中运行,但在 Visual Studio 中仍然无法运行。
错误的原因是它将emplace_back尝试构建map类似的vector:
std::map<int, std::unique_ptr<int>>(std::make_pair(...))
Run Code Online (Sandbox Code Playgroud)
另请参阅:std::map构造函数
然而,这是不可能的,因为接受对的构造函数正在接受std::initializer_list<std::pair<K, V>>。不存在采用单个对的构造函数。正确的做法是:
map<int, unique_ptr>{std::make_pair(...)}
Run Code Online (Sandbox Code Playgroud)
然而,构造函数std::initializer_list<T>要求 T是可复制的,而std::unique_ptr<int>不是可复制的,因此包含的T = std::pair<int, std::unique_ptr<int>>也是不可复制的。这给我们留下了以下解决方案:
#include <iostream>
#include <map>
#include <vector>
#include <memory>
int main()
{
using map_type = std::map<int, std::unique_ptr<int>>;
std::vector<map_type> data{};
for (int x = 0; x < 10; x++)
{
for (int y = 0; y < 10; y++)
{
map_type m;
m.emplace(x, std::make_unique<int>(y));
data.emplace_back(std::move(m));
}
}
}
Run Code Online (Sandbox Code Playgroud)
查看实例
在MSVC的标准库中,不可能使用std::vector<std::map<int, std::unique_ptr<int>>. 原因是,由于强异常保证,std::vector要求其元素类型为std::nothrow_move_constructible或 可复制。
您可以看到在 MSVC STL 中,std::map有非noexcept移动构造函数:
map(map&& _Right) : _Mybase(_STD move(_Right)) {}
Run Code Online (Sandbox Code Playgroud)
这是解决此问题的快速而肮脏的方法:
template <typename K, typename V>
struct nothrow_map : std::map<K, V> {
nothrow_map() = default;
nothrow_map(nothrow_map&& other) noexcept : std::map<K, V>(std::move(other)) {}
};
// ...
using map_type = nothrow_map<int, std::unique_ptr<int>>;
Run Code Online (Sandbox Code Playgroud)
另请参阅:(内部std::move_if_noexcept使用std::vector)
| 归档时间: |
|
| 查看次数: |
118 次 |
| 最近记录: |