2015-11-10 63 views
1

是否可以在boost::multi_index_container 中创建索引,该索引仅索引容器中的某些元素?索引boost :: multi_index_container中是否可以索引某些元素?

如果你有一个升压多指数容器:

using Nodes = boost::multi_index_container< 
    Node, 
    indexed_by< 
     sequenced<>, 
     ordered_unique< 
      tag<ordered_by_parent_id>, 
      const_mem_fun<Node, boost::optional<unsigned int>, &Node::parentId> 
     > 
    > 
>; 

,其中在容器中的元素有一个方法

const boost::optional<int> Node::parentId() 

你可能想对Node::parentId() 但如果返回值的索引你实际上只需要非空值的索引, 为集合中的所有元素创建一个索引似乎很浪费。

你可以创建第二个std容器,该容器包含指向具有有效父id的节点的子集 的指针,但是有没有一种很好的方法将其作为多索引容器上的附加索引处理?

+0

我能想到的唯一的事情是parentId的非唯一索引。您可以忽略空条目。 –

回答

2

不,你不能。

当然,您可以拥有非唯一索引,但对于所有无父条目仍具有开销。

可以做什么,但是,是把指针放在一个单独的“索引”容器。然后负责来保护这些容器的同步(以及指向对象的生命期)。

更新你甚至可以透明地使用参考包装:

using ParentIndex = bmi::multi_index_container< 
    boost::reference_wrapper<Node const>, 
    bmi::indexed_by< 
     bmi::ordered_non_unique< 
      bmi::tag<struct ordered_by_parent_id>, 
      bmi::const_mem_fun<Node, boost::optional<unsigned int>, &Node::parentId> 
     > 
    > 
>; 

这里有一个演示:

Live On Coliru

#include <boost/multi_index_container.hpp> 
#include <boost/multi_index/sequenced_index.hpp> 
#include <boost/multi_index/ordered_index.hpp> 
#include <boost/multi_index/mem_fun.hpp> 
#include <boost/optional.hpp> 
#include <boost/optional/optional_io.hpp> 
#include <iostream> 

namespace bmi = boost::multi_index; 

struct Node { 
    unsigned int Id; 
    boost::optional<unsigned int> for_demo; 
    boost::optional<unsigned int> parentId() const { return for_demo; }; 
}; 

static std::ostream& operator<<(std::ostream& os, Node const& n) { 
    return os << "{" << n.Id << ", " << n.parentId() << "}"; 
} 

using Nodes = bmi::multi_index_container< 
    Node, 
    bmi::indexed_by< 
     bmi::sequenced<> 
    > 
>; 

using ParentIndex = bmi::multi_index_container< 
    boost::reference_wrapper<Node const>, 
    bmi::indexed_by< 
     bmi::ordered_non_unique< 
      bmi::tag<struct ordered_by_parent_id>, 
      bmi::const_mem_fun<Node, boost::optional<unsigned int>, &Node::parentId> 
     > 
    > 
>; 

int main() { 
    Nodes table { 
     {1, boost::none}, {2, 5}, {3, boost::none}, {4, 5}, {5, 5}, {6, 2} 
    }; 

    ParentIndex extra; 
    for (auto const& e : table) 
     if (e.parentId()) extra.emplace(e); 

    for (auto& e : table) 
     std::cout << e.Id << " "; 

    std::cout << "\nParented: "; 

    for (Node const& e : extra) 
     std::cout << e << "; "; 
} 
+0

使用'reference_wrapper '添加了一个概念验证:[coliru](http://coliru.stacked-crooked.com/a/715d403f86f1a0cd) – sehe