c++ - 如何迭代 Boost Multi_index 容器的索引?

标签 c++ boost boost-multi-index boost-preprocessor

我有一个boost::multi_index::multi_index_container具有六个不同的容器ordered_non_unique指数。这个想法是能够沿着这六个索引对数据进行排序(作为使用多个标准对解决方案进行排名的一种手段)。

我面临的问题是在循环中检索索引时。 Boost 要求我使用以下语法来获取(比如说)第四个索引:

const result_multi::nth_index<1>::type &legs_index = result.get<4>();

我想做的是将上面的语句放入一个在 0 到 5 之间运行的循环中,以便我可以在所有六个索引上使用相同的代码。当然,下面的代码片段将无法编译:

for (size_t i = 0; i < 5; ++i) {
  const result_multi::nth_index<1>::type &index = result.get<i>();
  ...
  ... Display result sorted along the i-th index
  ...
 }

作为get<i>是一个需要在编译时定义的模板。

如何使用实现上述功能而不需要重复代码 6 次?看来boost:preprocessor可能有助于这样做,但我无法弄清楚如何使用它 - 任何指示将非常感激!

编辑:我也非常感谢非 C++11 解决方案,以补充使用一个非 C++11 解决方案的优秀答案。 (出于非技术原因,我被迫使用旧版本的 gcc)。

最佳答案

如果您无法使用 C++14,则使用 Boost 向后移植到 C++03 可能如下所示:

Live Coliru Demo

#include <boost/type_traits/integral_constant.hpp>

template<typename T,T N0,T N1,typename F>
void static_for(F f)
{
  static_for<T,N0,N1>(f,boost::integral_constant<bool,(N0<N1)>());
}

template<typename T,T N0,T N1,typename F>
void static_for(F f,boost::true_type)
{
  f(boost::integral_constant<T,N0>());
  static_for<T,N0+1,N1>(f);
}

template<typename T,T N0,T N1,typename F>
void static_for(F f,boost::false_type)
{
}

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

using namespace boost::multi_index;
typedef multi_index_container<
  int,
  indexed_by<
    ordered_non_unique<identity<int> >,
    ordered_non_unique<identity<int>,std::greater<int> >,
    ordered_non_unique<identity<int> >,
    ordered_non_unique<identity<int>,std::greater<int> >,
    ordered_non_unique<identity<int> >,
    ordered_non_unique<identity<int>,std::greater<int> >
  >
> result_multi;

#include <iostream>

struct body
{
  body(result_multi& result):result(result){}

  template<typename I>
  void operator()(I){
    typename result_multi::nth_index<I::value>::type& index=
      result.get<I::value>();

    std::cout<<"index #"<<I::value<<": ";
    for(typename result_multi::nth_index<I::value>::type::iterator
          b=index.begin(),
          e=index.end();
        b!=e;++b){
      std::cout<<*b<<" ";
    }
    std::cout<<"\n";
  }

  result_multi& result;
};

int main()
{
  result_multi result;
  for(int i=0;i<3;++i)result.insert(i);

  static_for<int,0,6>(body(result));
}

这相当难看。另一种选择是将预处理器与 BOOST_PP_REPEAT 一起使用。 。我自己不确定哪种解决方案看起来最好,但我认为我更喜欢第一个,因为它为 C++14 升级做好了更好的准备:

Live Coliru Demo

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

using namespace boost::multi_index;
typedef multi_index_container<
  int,
  indexed_by<
    ordered_non_unique<identity<int> >,
    ordered_non_unique<identity<int>,std::greater<int> >,
    ordered_non_unique<identity<int> >,
    ordered_non_unique<identity<int>,std::greater<int> >,
    ordered_non_unique<identity<int> >,
    ordered_non_unique<identity<int>,std::greater<int> >
  >
> result_multi;

#include <boost/preprocessor/repetition/repeat.hpp>
#include <iostream>

int main()
{
  result_multi result;
  for(int i=0;i<3;++i)result.insert(i);

#define BODY(z,i,_)                                        \
{                                                          \
  result_multi::nth_index<i>::type& index=result.get<i>(); \
                                                           \
  std::cout<<"index #"<<i<<": ";                           \
  for(result_multi::nth_index<i>::type::iterator           \
        b=index.begin(),                                   \
        e=index.end();                                     \
      b!=e;++b){                                           \
    std::cout<<*b<<" ";                                    \
  }                                                        \
  std::cout<<"\n";                                         \
}

BOOST_PP_REPEAT(6,BODY,~)

#undef BODY
}

关于c++ - 如何迭代 Boost Multi_index 容器的索引?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38279346/

相关文章:

c++ - Boost:多索引:如何迭代与非唯一有序索引匹配的所有结果?

c++ - Variadic 模板和类型推导问题

c++ - 强制 node-gyp 使用 C++11

c# - Protobuf-net 与 C++ 的官方谷歌 Protobuf 不兼容(消息编码)

c++ - boost::future 和 std::future 的不同行为

c++ - boost::multi_index_container 编译错误由于索引 typedef 上的类型不完整

c++ - 模板类中的 setter

c++ - Boost:错误的模板参数数量

c++ - 为什么默认构造的迭代器可以用于单程结束地标?

c++ - 使用值为 std::shared_ptr 的映射是否是具有多索引类列表的良好设计选择?