Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/129.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 是否有任何方法可以将元素从有序索引移动到多索引?_C++_Boost_Extract_Multi Index - Fatal编程技术网

C++ 是否有任何方法可以将元素从有序索引移动到多索引?

C++ 是否有任何方法可以将元素从有序索引移动到多索引?,c++,boost,extract,multi-index,C++,Boost,Extract,Multi Index,自C++17以来,std::set具有支持从容器中移动节点的extract()成员函数。下面是一个示例代码: #include <iostream> #include <cassert> #include <set> struct trace { trace() { std::cout << this << ":" << " construct" << std::endl; }

自C++17以来,
std::set
具有支持从容器中移动节点的
extract()
成员函数。下面是一个示例代码:

#include <iostream>
#include <cassert>
#include <set>

struct trace {
    trace() {
        std::cout << this << ":" << " construct" << std::endl;
    }
    ~trace() {
        std::cout << this << ":" << " destruct" << std::endl;
    }
    trace(trace& other) {
        std::cout << this << ":" << " copy construct from " << &other << std::endl;
    }
    trace(trace&& other) {
        std::cout << this << ":" << " move construct from " << &other << std::endl;
    }
    trace& operator=(trace const& other) {
        std::cout << this << ":" << " copy assign from    " << &other << std::endl;
        return *this;
    }
    trace& operator=(trace&& other) {
        std::cout << this << ":" << " move assign from    " << &other << std::endl;
        return *this;
    }
};

inline bool operator<(trace const& lhs, trace const& rhs) {
    std::cout << &lhs << " < " << &rhs << std::endl;
    return &lhs < &rhs;
}

int main () {
    std::set<trace> s;
    s.insert(trace());
    s.insert(trace());
    s.insert(trace());
    auto it = s.begin();
    ++it;

    assert(s.size() == 3);
    std::cout << "[[extract]]" << std::endl;
    trace t = std::move(s.extract(it).value());
    assert(s.size() == 2);
}
正在运行演示:

并得到以下输出:

[[modify]]
0x7fffe1f77c66: move construct from 0x55fdda3272e0
0x55fdda3272b0 < 0x55fdda3272e0
0x55fdda3272e0 < 0x55fdda327310
[[erase]]
0x55fdda3272e0: destruct
0x7fffe1f77c66: destruct
0x55fdda3272b0: destruct
0x55fdda327310: destruct
[[modify]]
0x7fffe1f77c66:从0x55fdda3272e0移动构造
0x55fdda3272b0<0x55fdda3272e0
0x55fdda3272e0<0x55fdda327310
[[删除]]
0x55fdda3272e0:自毁
0x7fffe1f77c66:自毁
0x55fdda3272b0:自毁
0x55fdda327310:自毁
multi_index
返回modify lambda后从对象(
0x55fdda3272e0
)移动的容器访问。我认为这是为了重新订购
modify()
不知道我将
modify()
erase()
一起使用。对于
random\u access\u index
,它工作得很好,因为容器不需要重新排序,但对于
ordered\u index
它不工作


是否有任何方法可以从
有序索引
ed
多索引
中移动元素?

您可以使用以下方法从
多索引容器
中提取值,同时确保在提取值后立即删除元素:

struct extract_value_exception{};

template<typename MultiIndexContainerIndex>
auto extract_value(
    MultiIndexContainerIndex& i,
    typename MultiIndexContainerIndex::iterator it)
{
    using value_type = typename MultiIndexContainerIndex::value_type;

    std::optional<value_type> o;
    try{
        i.modify(it, [&](value_type& x){
            o.emplace(std::move(x));
            throw extract_value_exception{};
        });
    }
    catch(const extract_value_exception&){}
    return std::move(*o);
}
struct extract\u value\u exception{};
样板
自动提取u值(
MultiIndexContainerIndex&i,
typename MultiIndexContainerIndex::迭代器(it)
{
使用value\u type=typename MultiIndexContainerIndex::value\u type;
std::可选o;
试一试{
i、 修改(它,[&](值类型&x){
o、 炮位(std::move(x));
抛出提取值异常{};
});
}
catch(const extract_value_exception&){
返回标准::移动(*o);
}
完整的例子如下

#include <boost/multi_index_container.hpp>
#include <boost/multi_index/identity.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <cassert>
#include <iostream>
#include <optional>

struct trace {
    trace() {
        std::cout << this << ":" << " construct" << std::endl;
    }
    ~trace() {
        std::cout << this << ":" << " destruct" << std::endl;
    }
    trace(trace& other) {
        std::cout << this << ":" << " copy construct from " << &other << std::endl;
    }
    trace(trace&& other) {
        std::cout << this << ":" << " move construct from " << &other << std::endl;
    }
    trace& operator=(trace const& other) {
        std::cout << this << ":" << " copy assign from    " << &other << std::endl;
        return *this;
    }
    trace& operator=(trace&& other) {
        std::cout << this << ":" << " move assign from    " << &other << std::endl;
        return *this;
    }
};

inline bool operator<(trace const& lhs, trace const& rhs) {
    std::cout << &lhs << " < " << &rhs << std::endl;
    return &lhs < &rhs;
}

struct extract_value_exception{};

template<typename MultiIndexContainerIndex>
auto extract_value(
    MultiIndexContainerIndex& i,
    typename MultiIndexContainerIndex::iterator it)
{
    using value_type = typename MultiIndexContainerIndex::value_type;

    std::optional<value_type> o;
    try{
        i.modify(it, [&](value_type& x){
            o.emplace(std::move(x));
            throw extract_value_exception{};
        });
    }
    catch(const extract_value_exception&){}
    return std::move(*o);
}

int main () {
    boost::multi_index_container<trace> s;
    s.insert(trace());
    s.insert(trace());
    s.insert(trace());
    auto it = s.begin();
    ++it;

    assert(s.size() == 3);
    std::cout << "[[extract]]" << std::endl;
    trace t = extract_value(s, it);
    assert(s.size() == 2);
}
#包括
#包括
#包括
#包括
#包括
#包括
结构跟踪{
跟踪(){

std::难道你的问题很难理解吗。让我们看第一部分-输出对我来说很好。你期望什么输出?第一部分输出很好。最后一部分输出很差,因为0x55fdda3272e0在移动后被访问。我想做与使用
boost::muti_index
有序索引的
std::set::extract
相同的事情。我仍然不确定您试图实现什么。您有一个迭代器
,它指向您需要的元素,如果您想从中移动,只需从容器中移动并删除它。这有什么问题吗?是的,它是有意义的。谢谢!它非常有效。如果有人担心性能,请参阅。我们可以使用
extract()
用于将来的
多索引
struct extract_value_exception{};

template<typename MultiIndexContainerIndex>
auto extract_value(
    MultiIndexContainerIndex& i,
    typename MultiIndexContainerIndex::iterator it)
{
    using value_type = typename MultiIndexContainerIndex::value_type;

    std::optional<value_type> o;
    try{
        i.modify(it, [&](value_type& x){
            o.emplace(std::move(x));
            throw extract_value_exception{};
        });
    }
    catch(const extract_value_exception&){}
    return std::move(*o);
}
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/identity.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <cassert>
#include <iostream>
#include <optional>

struct trace {
    trace() {
        std::cout << this << ":" << " construct" << std::endl;
    }
    ~trace() {
        std::cout << this << ":" << " destruct" << std::endl;
    }
    trace(trace& other) {
        std::cout << this << ":" << " copy construct from " << &other << std::endl;
    }
    trace(trace&& other) {
        std::cout << this << ":" << " move construct from " << &other << std::endl;
    }
    trace& operator=(trace const& other) {
        std::cout << this << ":" << " copy assign from    " << &other << std::endl;
        return *this;
    }
    trace& operator=(trace&& other) {
        std::cout << this << ":" << " move assign from    " << &other << std::endl;
        return *this;
    }
};

inline bool operator<(trace const& lhs, trace const& rhs) {
    std::cout << &lhs << " < " << &rhs << std::endl;
    return &lhs < &rhs;
}

struct extract_value_exception{};

template<typename MultiIndexContainerIndex>
auto extract_value(
    MultiIndexContainerIndex& i,
    typename MultiIndexContainerIndex::iterator it)
{
    using value_type = typename MultiIndexContainerIndex::value_type;

    std::optional<value_type> o;
    try{
        i.modify(it, [&](value_type& x){
            o.emplace(std::move(x));
            throw extract_value_exception{};
        });
    }
    catch(const extract_value_exception&){}
    return std::move(*o);
}

int main () {
    boost::multi_index_container<trace> s;
    s.insert(trace());
    s.insert(trace());
    s.insert(trace());
    auto it = s.begin();
    ++it;

    assert(s.size() == 3);
    std::cout << "[[extract]]" << std::endl;
    trace t = extract_value(s, it);
    assert(s.size() == 2);
}
0x7ffd5feed89d: construct
0x21f7190: move construct from 0x7ffd5feed89d
0x7ffd5feed89d: destruct
0x7ffd5feed89e: construct
0x7ffd5feed89e < 0x21f7190
0x21f7190 < 0x7ffd5feed89e
0x21f71c0: move construct from 0x7ffd5feed89e
0x7ffd5feed89e: destruct
0x7ffd5feed89f: construct
0x7ffd5feed89f < 0x21f7190
0x7ffd5feed89f < 0x21f71c0
0x21f71c0 < 0x7ffd5feed89f
0x21f71f0: move construct from 0x7ffd5feed89f
0x7ffd5feed89f: destruct
[[extract]]
0x7ffd5feed836: move construct from 0x21f71c0
0x21f71c0: destruct
0x7ffd5feed867: move construct from 0x7ffd5feed836
0x7ffd5feed836: destruct
0x7ffd5feed867: destruct
0x21f7190: destruct
0x21f71f0: destruct