如何从boost :: multi_index_container检索元素

时间:2019-07-03 11:51:45

标签: c++ boost

我正在尝试使用唯一的数字ID索引从boost::multi_index_container检索值。我以前从未使用过boost::multi_index_container,因此在理解它们的工作方式时遇到了一些麻烦。它们似乎像数据库一样工作,我要做的就是通过指定id来检索项目。任何帮助将不胜感激。

这是数据类型:

typedef boost::multi_index_container<
    // Multi index container holds pointers to the subnets.
    Subnet6Ptr,
    // The following holds all indexes.
    boost::multi_index::indexed_by<
        // First is the random access index allowing for accessing
        // objects just like we'd do with a vector.
        boost::multi_index::random_access<
            boost::multi_index::tag<SubnetRandomAccessIndexTag>
        >,
        // Second index allows for searching using subnet identifier.
        boost::multi_index::ordered_unique<
            boost::multi_index::tag<SubnetSubnetIdIndexTag>,
            boost::multi_index::const_mem_fun<Subnet, SubnetID, &Subnet::getID>
        >,
        // Third index allows for searching using an output from toText function.
        boost::multi_index::ordered_unique<
            boost::multi_index::tag<SubnetPrefixIndexTag>,
            boost::multi_index::const_mem_fun<Subnet, std::string, &Subnet::toText>
        >
    >
> Subnet6Collection;

dhcpv6-server(KEA)加载其配置文件时,将创建Subnet6Collection对象。该文件为每个子网SubnetID的数据类型包含一个可选的数字ID值。

我想通过指定Subnet6Ptr来检索SubnetID

2 个答案:

答案 0 :(得分:1)

是的,Mutli-index可能很难使用。正如我在a different answer中所写的那样,“ Boost.Multi-index提供了一个非常可定制的界面,但以提供一个非常复杂的界面为代价。”

基本上,当您要访问容器的内容时​​,可以通过其索引之一进行操作。因此,您首先获得对要使用的索引的引用(在您的情况下为标记的SubnetSubnetIdIndexTag),然后将该索引视为容器。哪个容器取决于索引的类型。对于经过排序的唯一索引(如您的情况),有点像std::map(但是迭代器仅指向值),或者像std::set那样带有仅比较ID的透明比较器。

这是代码中的样子:

Subnet6Collection coll = something();
SubnetID idToLookFor = something2();

auto& indexById = coll.index<SubnetSubnetIdIndexTag>();
auto it = index.find(idToLookFor);
if (it != index.end()) {
  Subnet6Ptr p = *it;
} else {
  // No such ID found
}

答案 1 :(得分:0)

感谢您的回答。

我尝试了以下操作(SubnetID只是uint32_t,所以我使用10进行测试):

SubnetID id = 10;
Subnet6Collection coll;

auto& indexById = coll.index<SubnetSubnetIdIndexTag>();
auto it = index.find(id);
if (it != index.end()) {
  Subnet6Ptr p = *it;
} else {
  // No such ID found
}

但无法编译:

Opt18_lease_select.cc:38:24:错误:无效使用'struct boost :: multi_index :: multi_index_container,boost :: multi_index :: indexed_by>,boost :: multi_index :: ordered_unique,boost :: multi_index :: const_mem_fun >,boost :: multi_index :: ordered_unique,boost :: multi_index :: const_mem_fun,&isc :: dhcp :: Subnet :: toText>>>> :: index'

auto& indexById = coll.index<SubnetSubnetIdIndexTag>();
                        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Opt18_lease_select.cc:39:17:错误:函数重载,没有上下文类型信息

 auto it = index.find(id);
                 ^~~~

Opt18_lease_select.cc:40:17:错误:函数重载,没有上下文类型信息

 if (it != index.end()) {
                 ^~~

似乎无法以这种方式使用index()find(),end(),或者也许我只是缺少一些头文件?