澄清Boost多索引容器

时间:2015-11-20 16:40:11

标签: c++ dictionary boost

我正在尝试了解Boost多指数,请为此寻求一些帮助。

数据如下所示:

 index1, index2, index3, index4, value
 alpha   a       1       101     0.5
 alpha   a       1       102     0.6
 ...    ...     ...     ....     ...
 alpha   a       1       120     0.7
 alpha   a       2       101     0.3
 ...    ...     ...     ....     ... 
 alpha   a       2       101     0.3
 alpha   b       1       101     0.3
 ...    ...     ...     ....     ...
 beta   a       1       101     0.7
 ...    ...     ...     ....     ...

现在我已经创建了一个结构:

struct data
{
   data(std::string index1,
      std::string index2,
      int index3,
      int index4,
      double value):index1_(index1),index2_(index2),index3_(index3),
      index4_(index4),value_(value){}
    std::string index1_;
    std::string index2_;
    int index3_;
    int index4_;    
    double value_;
};

并且还有:

struct index1{};
struct index2{};
struct index3{};
struct index4{};
struct value{}; // I guess i do not need this because this is a data point
                // and not an index. Can someone please comment ?

接下来我创建了一个typedef,如下所示:我不确定是否使用" ordered_unique"或" ordered_non_unique"。有人可以请帮助。

我有困惑,因为4元组(index1,index2,index3,inde4)是指向数据值的唯一坐标。但是对于它们中的每一个都会重复出现(例如对于index1字符串" alpha"重复几次)

typedef boost::multi_index::multi_index_container<
    data, boost::multi_index::indexed_by<
           boost::multi_index::ordered_unique<boost::multi_index::tag<index1>,boost::multi_index::member<data, std::string,&data::index1_> >,
           boost::multi_index::ordered_unique<boost::multi_index::tag<index2>,boost::multi_index::member<data, std::string,&data::index2_> >,
           boost::multi_index::ordered_unique<boost::multi_index::tag<index3>,boost::multi_index::member<data, int,&data::index3_> >,
           boost::multi_index::ordered_unique<boost::multi_index::tag<index4>,boost::multi_index::member<data, int,&data::index4_> >,

     // not sure if I need the line below. because it is not an index

           boost::multi_index::ordered_unique<boost::multi_index::tag<value>,boost::multi_index::member<data, double,&data::value_> >,
       >
    > data_map;  

接下来在main()中我通过循环遍历每个数据点来填充数据并执行插件,如下所示:

 data_map DATA;
 DATA.insert(data(alpha,a,1,101,0.5));

此后,我想检查一下index4的范围是什么(即最小值和最大值是多少)。我正在尝试类似的事情:

    const boost::multi_index::index<data_map,index4>::type& in_index4 = boost::multi_index::get<index4>(DATA);
    int nIndex4 = in_index4.size(); // I do not get the correct size here

此外,当我尝试时,我没有得到预期的结果。

    boost::multi_index::index<data_map,index4>::type::const_iterator index_itr=in_index4.begin();
    for(;index_itr!=in_index4.end();index_itr++)
    {
        int xx = (*index_itr).index4_;
    }

有人可以指出我的错误并帮助我理解。 提前致谢

1 个答案:

答案 0 :(得分:2)

  

struct value{}; // I guess i do not need this because this is a data point
                // and not an index. Can someone please comment ?

仅创建您使用的索引。

  

问。我不确定是使用ordered_unique还是ordered_non_unique。有人可以帮忙。

     

我有困惑,因为4元组(index1,index2,index3,inde4)是指向数据值的唯一坐标。但是对于它们中的每一个都会重复出现(例如对于index1字符串&#34; alpha&#34;重复多次)

您需要复合键上的唯一索引:

bmi::indexed_by<
    bmi::ordered_unique<
        bmi::composite_key<data,
            bmi::member<data, std::string, &data::index1_>,
            bmi::member<data, std::string, &data::index2_>,
            bmi::member<data, int,         &data::index3_>,
            bmi::member<data, int,         &data::index4_>
        >
    >
>
  

问。接下来在main()中我通过循环遍历每个数据点来填充数据并执行插件,如下所示:

我可以建议统一初始化:

Table table {
    //index1, index2, index3, index4, value
    data {   "alpha", "a", 1, 101, 0.5 },
    data {   "alpha", "a", 1, 102, 0.6 },
    // ...
    data {   "alpha", "a", 1, 120, 0.7 },
    data {   "alpha", "a", 2, 101, 0.3 },
    // ...
    data {   "alpha", "a", 2, 101, 0.3 },
    data {   "alpha", "b", 1, 101, 0.3 },
    // ...
    data {   "beta",  "a", 1, 101, 0.7 },
};
  

问。此后,我想检查一下index4的范围是什么(即最小值和最大值是多少)。我正在尝试这样的事情:

  const boost::multi_index::index<data_map,index4>::type& in_index4 = boost::multi_index::get<index4>(DATA);
  int nIndex4 = in_index4.size(); // I do not get the correct size here
无论如何,

size()返回容器中的元素数量。您可以添加索引

bmi::ordered_non_unique<
    bmi::tag<struct index4>, bmi::member<data, int, &data::index4_>
>

和&#34;利用&#34;这是订购的事实:

int min4 = table.get<index4>().begin() ->index4_;
int max4 = table.get<index4>().rbegin()->index4_;

完整演示

<强> 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 <string>
#include <iostream>

struct data
{
    std::string index1_;
    std::string index2_;
    int         index3_;
    int         index4_;
    double      value_;
};

namespace bmi = boost::multi_index;

using Table = bmi::multi_index_container<
    data, bmi::indexed_by<
        bmi::ordered_unique<
            bmi::composite_key<data,
                bmi::member<data, std::string, &data::index1_>,
                bmi::member<data, std::string, &data::index2_>,
                bmi::member<data, int,         &data::index3_>,
                bmi::member<data, int,         &data::index4_>
            >
        >,
        bmi::ordered_non_unique<
            bmi::tag<struct index4>,
            bmi::member<data, int, &data::index4_>
        >
    >
>;

int main() {
    Table table {
        //index1, index2, index3, index4, value
        data {   "alpha", "a", 1, 101, 0.5 },
        data {   "alpha", "a", 1, 102, 0.6 },
        // ...
        data {   "alpha", "a", 1, 120, 0.7 },
        data {   "alpha", "a", 2, 101, 0.3 },
        // ...
        data {   "alpha", "a", 2, 101, 0.3 },
        data {   "alpha", "b", 1, 101, 0.3 },
        // ...
        data {   "beta",  "a", 1, 101, 0.7 },
    };

    // max min index4, exploiting the ordered-ness of the index
    if (!table.empty()) {
        int min4 = table.get<index4>().begin() ->index4_;
        int max4 = table.get<index4>().rbegin()->index4_;

        std::cout << "index4: " << min4 << " - " << max4 << "\n";
    }
}

打印:

index4: 101 - 120