我的应用程序中有一个boost::multi_index
容器,它包含对象的共享指针(std::shared_ptr
)。正如我从文档中所理解的那样,它创建了一个树结构,并在唯一索引上进行双向访问。是否可以告诉容器具有一个数组结构,该结构具有对唯一索引的随机访问(类似boost::flat_set
)?
答案 0 :(得分:3)
您当然可以完全按照您的描述进行操作:
<强> Live On Coliru 强>
#include <boost/container/flat_set.hpp>
#include <memory>
#include <vector>
#include <iostream>
template <typename V, typename... Init>
auto make_shared_flat_set(Init&&... values) {
return boost::container::flat_set<std::shared_ptr<V> > {
std::make_shared<V>(std::forward<Init>(values))...
};
}
int main() {
using sptr = std::shared_ptr<std::string>;
auto const set = make_shared_flat_set<std::string>("one", "two", "three", "four", "Hungary");
// the set-like interface: (ordered_unique)
std::cout << "set: ";
for (auto& e : set) std::cout << *e << " ";
{
// let's make a random access copy:
std::vector<sptr> random_access(set.begin(), set.end());
std::cout << "\ncopy: ";
for (auto& e : random_access) std::cout << *e << " ";
}
{
// let's make a random access view:
using spref = std::reference_wrapper<sptr const>;
std::vector<spref> random_access(set.begin(), set.end());
std::cout << "\nview: ";
for (sptr const& e : random_access) std::cout << *e << " ";
}
}
打印
set: one two three four Hungary
copy: one two three four Hungary
view: one two three four Hungary
<强> Live On Coliru 强>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/identity.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/random_access_index.hpp>
#include <memory>
#include <iostream>
namespace bmi = boost::multi_index;
template <typename V> using Table = bmi::multi_index_container<std::shared_ptr<V>,
bmi::indexed_by<
bmi::random_access<bmi::tag<struct ra_idx> >,
bmi::ordered_unique<bmi::tag<struct set_idx>, bmi::identity<V> >
>
>;
template <typename V, typename... Init>
auto make_shared_flat_set(Init&&... values) {
return Table<std::string> {
std::make_shared<V>(std::forward<Init>(values))...
};
}
int main() {
auto const set = make_shared_flat_set<std::string>("one", "two", "three", "four", "Hungary");
// the set-like interface: (ordered_unique)
auto& as_set = set.get<set_idx>();
std::cout << "set: ";
for (auto& e : as_set) std::cout << *e << " ";
// the random access interface:
std::cout << "\nrandom access: ";
auto& random_access = set.get<ra_idx>();
for (auto& e : random_access) std::cout << *e << " ";
}
打印:
set: Hungary four one three two
random access: one two three four Hungary
要将random_access索引放入与set相同的顺序,请使用重新排列:
// put the random access in the same order as the set:
random_access.rearrange(make_ro_view(as_set).begin());
std::cout << "\nrandom access (rearranged): ";
for (auto& e : random_access) std::cout << *e << " ";
<强> Live On Coliru 强>
打印
set: Hungary four one three two
random access: one two three four Hungary
random access (rearranged): Hungary four one three two
答案 1 :(得分:3)
添加到sehe的答案中,Boost.MultiIndex有ranked indices提供对数时间位置访问,与通常的有序索引接口相对 - 不完全是随机访问,但可能足以满足您的需求。
<强> Live On Coliru 强>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/identity.hpp>
#include <boost/multi_index/ranked_index.hpp>
#include <memory>
#include <iostream>
namespace bmi = boost::multi_index;
template <typename V> using Table = bmi::multi_index_container<std::shared_ptr<V>,
bmi::indexed_by<
bmi::ranked_unique<bmi::tag<struct set_idx>, bmi::identity<V> >
>
>;
template <typename V, typename... Init>
auto make_shared_flat_set(Init&&... values) {
return Table<std::string> {
std::make_shared<V>(std::forward<Init>(values))...
};
}
int main() {
auto const set = make_shared_flat_set<std::string>("one", "two", "three", "four", "Hungary");
std::cout << "set: ";
for (auto& e : set) std::cout << *e << " ";
// the random access interface:
std::cout << "\npositional access: ";
for (std::size_t n = 0; n < set.size(); ++n) std::cout << **set.nth(n) << " ";
}
打印
set: Hungary four one three two
positional access: Hungary four one three two