如何从STL容器中获得仅限移动类型
How to get a move-only type out of a STL container?
以std::unique_ptr<T>
的std::unordered_set
为例。我可以把集合中的元素移到别处吗?
#include <unordered_set>
#include <iostream>
#include <memory>
#include <vector>
int main()
{
std::unordered_set<std::unique_ptr<int>> mySet;
mySet.insert(std::make_unique<int>(1));
mySet.insert(std::make_unique<int>(2));
mySet.insert(std::make_unique<int>(3));
std::vector<std::unique_ptr<int>> myVector;
for (auto&& element : mySet)
{
std::cout << *element << std::endl;
//myVector.push_back(element); won't compile as you can only get a const ref to the key
}
}
我有一个非常实用的代码示例,我想这样做,但我减少了使用std::shared_ptr
。你知道另一种(更好的)选择吗?
在c++ 03、c++ 11和c++ 14中,不直接。您必须将类型更改为:
template <class T>
struct handle {
mutable std::unique_ptr<T> owning_ptr;
T* observing_ptr; // enforce that observing_ptr == owning_ptr.get() on construction
// define operator<, hash, etc. in terms of the observing ptr
};
你可以这样写:
std::unordered_set<handle<int>> mySet;
// initialize as appropriate
for (auto& elem : mySet) {
myVector.push_back(std::move(elem.owning_ptr));
}
mySet.clear();
这仍然是定义良好的行为,因为我们没有弄乱任何容器内部-观察指针在clear()
结束时仍然有效,只是现在myVector
拥有它。
在c++ 17中,我们可以通过extract()
:
for (auto it = mySet.begin(); it != mySet.end();
{
std::cout << **it << std::endl;
myVector.push_back(std::move(
mySet.extract(it++).value()));
}
相关文章:
- 在从仅移动类型派生的类中定义析构函数在使用 std::vector emplace_back或push_back创建时会
- 对于可移动类型,按值传递比重载函数更好吗?
- 强制复制(然后销毁)仅移动类型
- static_cast为仅移动类型的叮当与 GCC
- 从 std::set 中提取仅移动类型
- 具有抑制移动构造/赋值的类型如何仍被视为可移动类型?
- 包含仅移动类型的类的构造函数应通过引用还是通过右值引用接收仅移动类型?
- std::仅移动类型列表:不能在 VC++ 中放入 std::vector
- C :通过STD :: simolor_ptr(仅移动类型)rvalue作为参数时复制ELISION
- boost::变体对仅移动类型的处理中的奇怪行为
- 在可移动类型的构造函数 lambda 中捕获此内容的安全使用
- C 11 STL容器支持仅移动类型,并且具有O(1)写入访问的开始和结束
- boost::不可移动类型的变体
- 返回仅移动类型编译,即使复制构造函数不可用
- std::move_if_noexcept 仍然移动投掷仅移动类型的基本原理
- std::bind通常适用于仅移动类型,特别是std::unique_ptr
- 仅移动类型的back_inserter
- 构造函数中可移动类型的 C++ 右值
- 我可以列出初始化一个仅移动类型的向量吗?
- 如何在Visual c++ 9中使用类型特征检测按位移动类型?