c++ - boost multi_index - 如果元素类型为仅移动,如何将元素从一个容器添加到另一个容器?

标签 c++ boost

我有:

struct foo {
    ...
    std::unique_ptr<Bar> bar; // requires foo to be move-only
    foo() { bar = std::make_unique<Bar>(); }
    foo(foo&&) = default;
};

typedef boost::multi_index_container<
    foo,
    boost::multi_index::indexed_by< 
        boost::multi_index::random_access<>,
        boost::multi_index::hashed_unique<
            boost::multi_index::composite_key<
                foo,
                boost::multi_index::member<X,std::string,&X::zoo>,
            >
        >
    >
> MyContainerType;

还有这个 MyContainerType 的两个容器:

MyContainerType c1, c2;

有时我想遍历所有 c1 元素并将其中一些(根据某些逻辑)添加到 c2。 我试过:

for (auto it = c1.begin(); it != c1.end(); ++it) {
    if (...some logics... ) {
        c2.push_back(std::move(*it));
    }
}

但它无法编译,就像我尝试过的许多其他方法一样。

最佳答案

您可以使用该答案中概述的技巧:Move element from boost multi_index array (我将您链接到您之前的问题)。

Live On Coliru

#include <boost/multi_index_container.hpp>
#include <boost/multi_index/sequenced_index.hpp>
#include <boost/optional.hpp>
#include <iostream>

// move-only
struct foo {
    foo(int x) : x(x) {}
    foo(foo&&)      = default;
    foo(foo const&) = delete;
    foo& operator=(foo&&)      = default;
    foo& operator=(foo const&) = delete;

    int x;
};

template <typename Container>
void dump(std::ostream& os, Container const& c) { 
    for (auto& r: c) os << r.x << " ";
    os << "\n";
}

static_assert(not std::is_copy_constructible<foo>{}, "foo moveonly");

namespace bmi = boost::multi_index;

using foos = bmi::multi_index_container<foo, bmi::indexed_by<bmi::sequenced<> > >;

int main() {
    foos source, other;

    source.emplace_back(1);
    source.emplace_back(2);
    source.emplace_back(3);
    source.emplace_back(4);
    source.emplace_back(5);
    dump(std::cout << "Source before: ", source);

    for (auto it = source.begin(); it != source.end();) {
        if (it->x % 2) { // odd?
            boost::optional<foo> extracted;

            if (source.modify(it, [&](foo& v) { extracted = std::move(v); })) {
                it = source.erase(it);
            } else {
                ++it;
            }
            other.push_back(std::move(*extracted));
        } else {
            ++it;
        }
    }

    dump(std::cout << "Source after: ", source);
    dump(std::cout << "Other after: ", other);
}

这会将奇数项从 source 移动到 other:

Source before: 1 2 3 4 5 
Source after: 2 4 
Other after: 1 3 5 

关于c++ - boost multi_index - 如果元素类型为仅移动,如何将元素从一个容器添加到另一个容器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50547949/

相关文章:

c++ - 如何使用 QT RegExp 从字符串中提取子字符串列表

c++ - CUDA 中是否有预处理器宏告诉我们是否正在编译设备代码?

c++ - 内存将由空格分隔的 float 文本文件映射到 float vector

c++ - 帮助 boost 语法

c++ - 在 C++ 中传递命令行参数

c++ - HelloWindow对象是否被删除?

c++ - 无法在 Xcode 3 中打开文件

c++ - 将基类指针转换为派生类(引用)

android - 构建无版本号后缀的 boost

c++11 - 如何在 C++ 中实现类似 SQL 的容器