如何循环访问提升Multi_index容器的索引
How to iterate through the indices of a Boost Multi_index container?
我有一个boost::multi_index::multi_index_container
容器,有六个不同的ordered_non_unique
索引。这个想法是能够沿着这六个指数对数据进行排序(作为使用多个标准对解决方案进行排名的一种手段)。
我面临的问题是在循环中检索索引时。Boost 要求我使用以下语法来获取(例如)第 4 个索引:
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解决方案,以补充使用一个出色的答案。(出于非技术原因,我被迫使用gcc的旧版本)。
如果您不能使用 C++14,则使用 Boost 向后移植到 C++03 可能如下所示:
现场科里鲁演示
#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 升级做好了更好的准备:
现场科里鲁演示
#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
}
一些元编程来做到这一点,即将运行时for
替换为编译时构造,该结构可以迭代表示常量 0,...,5 的类型。下面显示了依赖于 C++14 功能的非常简单static_for
。注意,替换for
体的泛型lambda函数传递了一个std::integral_constant
i
,其数值是通过operator()
获得的,因此"auto& index=result.get<i()>();
"中的"i()
"。
现场科里鲁演示
#include <type_traits>
template<typename T,T N0,T N1,typename F>
void static_for(F f)
{
static_for<T,N0,N1>(f,std::integral_constant<bool,(N0<N1)>{});
}
template<typename T,T N0,T N1,typename F>
void static_for(F f,std::true_type)
{
f(std::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,std::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;
using result_multi=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>>
>
>;
#include <iostream>
int main()
{
result_multi result={0,1,2};
static_for<int,0,6>([&](auto i){
auto& index=result.get<i()>();
std::cout<<"index #"<<i()<<": ";
for(int x:index)std::cout<<x<<" ";
std::cout<<"n";
});
}
输出:
索引 #0: 0 1 2索引 #1: 2 1 0索引 #2: 0 1 2索引 #3: 2 1 0索引 #4: 0 1 2索引 #5: 2 1 0
- 在提升multi_index容器中,是否定义了"default index"?
- DrawIndexedInstanced 具有不同的 Index Count per Instance (Directx
- 有没有办法使用递归函数找到数组中最小值的 INDEX?C++
- 可视化C++:发布模式的运行时库作为'Multi-threaded Debug DLL'
- OpenGL VBO Indexing ( How to compute Index Array)
- "Warning: Comma within array index expression"但逗号分隔函数参数
- 如何根据排序索引的向量对 std::index 集进行排序?
- 在一行代码中理解 index++
- 为什么打印 c 样式字符串的'address of index n'会导致子字符串的输出
- boost beast Websocket Multi Request Server/Client 并不是真正的 mul
- 使用 std::get 访问 std::variant<index>
- 代码中的"vector<<int>vector>&index"是什么意思?
- c++如何使用Curl Multi-Interface连续循环
- CStringArray::GetAt(int index) 返回一个 const. 为什么?
- 如何配置 Doxygen 以在"Class Index"中包含类的类型定义?
- 在 R 中调用"multi file C++ code with external libraries referenced"
- 如何使用 std::get 作为 boost-multi-index 容器键的global_fun
- Boost Multi Index标识索引
- Boost Multi Index:基于列表内容的索引
- Boost Multi-Index中的多个索引查询