MultiIndex Container equal_range ..以相反的顺序获取输出

Nes*_*NS3 1 boost c++11

我有一个boost :: multiIndex容器。说:

typedef boost::multi_index<....
 > OrderSet;


OrderSet orderSet_;

int main()
{
    const auto it = orderSet_.get<0>().equal_range(boost::make_tuple(/* Some Values*/))
 if(it.first != it.second)
  while(it.second != it.first) { /* Somethings to do */; 
  --it.second;          
 }
}
Run Code Online (Sandbox Code Playgroud)

程序因offset_ptr错误而崩溃。该程序it具有递增顺序的价值。所以我想先获得最高的价值,然后再下去..是这样的boost::equal_range(..., [&](const auto a, const auto b)-> decltype bool{return a > b;}); 东西的重载功能吗?它像reverse_iteratorequal_range()

更新:一个生产者和许多消费者都可以访问多索引容器。当消费者找到equal_range时,生产者添加或删除元素,消费者抛出错误...这仅在我反向迭代时发生...

seh*_*ehe 5

您忽略了必要的部分:选定的索引类型。

不同的索引类型提供不同的接口。

然后,再次equal_range暗示有序或无序图。并且由于在无序地图上逆转顺序是没有意义的,因此我将假设有序地图。

接下来,在make_tuple那里,我正在猜测复合键。

#include <boost/multi_index_container.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/composite_key.hpp>

struct X {
    int i;
    std::string name;
};

namespace bmi = boost::multi_index;
typedef boost::multi_index_container<X,
        bmi::indexed_by<
            bmi::ordered_non_unique<
                bmi::tag<struct by_i>,
                bmi::composite_key<X,
                    bmi::member<X, int, &X::i>,
                    bmi::member<X, std::string, &X::name>
                >
            >
        >
 > OrderSet;
Run Code Online (Sandbox Code Playgroud)

然后是本机订单:

#include <iostream>

int main()
{
    std::cout << std::unitbuf;

    OrderSet orderSet_ {
        { 1, "one" }, { 1, "two" }, { 2, "three" }, { 3, "four" }, { 2, "five" }
    };

    auto const range = orderSet_/*.get<0>()*/.equal_range(boost::make_tuple(2));

    for (auto& el : boost::make_iterator_range(range))
        std::cout << el.i << "," << el.name << "; ";

    // ...
Run Code Online (Sandbox Code Playgroud)

我会使用Boost Range来获得相反的顺序:

#include <boost/range/adaptor/reversed.hpp>

   // ...

    // traverse these in reverse
    std::cout << "\nNow in reverse:\n";
    for (auto& el : range | boost::adaptors::reversed)
        std::cout << el.i << "," << el.name << "; ";
}
Run Code Online (Sandbox Code Playgroud)

红利

当然,您可以手动编写相同的代码:

std::cout << "\nAlso in reverse:\n";
auto it = orderSet_.get<0>().equal_range(boost::make_tuple(2));
while(it.second != it.first) {
    --it.second;

    auto& el = *it.second;
    std::cout << el.i << "," << el.name << "; ";
}
Run Code Online (Sandbox Code Playgroud)

现场演示

Live On Coliru

#include <boost/multi_index_container.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/composite_key.hpp>
#include <boost/range/adaptor/reversed.hpp>

struct X {
    int i; //  = [] { static int gen = 0; return ++gen; }();
    std::string name;
};

namespace bmi = boost::multi_index;
typedef boost::multi_index_container<X,
        bmi::indexed_by<
            bmi::ordered_non_unique<
                bmi::tag<struct by_i>,
                bmi::composite_key<X,
                    bmi::member<X, int, &X::i>,
                    bmi::member<X, std::string, &X::name>
                >
            >
        >
 > OrderSet;

#include <iostream>

int main()
{
    std::cout << std::unitbuf;

    OrderSet orderSet_ {
        { 1, "one" }, { 1, "two" }, { 2, "three" }, { 3, "four" }, { 2, "five" }
    };

    {
        auto const range = orderSet_/*.get<0>()*/.equal_range(boost::make_tuple(2));

        for (auto& el : boost::make_iterator_range(range))
            std::cout << el.i << "," << el.name << "; ";

        // traverse these in reverse
        std::cout << "\nNow in reverse:\n";
        for (auto& el : range | boost::adaptors::reversed)
            std::cout << el.i << "," << el.name << "; ";
    }

    {
        std::cout << "\nAlso in reverse:\n";
        auto it = orderSet_.get<0>().equal_range(boost::make_tuple(2));
        while(it.second != it.first) {
            auto& el = *(--it.second);
            std::cout << el.i << "," << el.name << "; ";
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

版画

2,five; 2,three; 
Now in reverse:
2,three; 2,five; 
Also in reverse:
2,three; 2,five; 
Run Code Online (Sandbox Code Playgroud)