I need to overload the [] operator for boost::multi_index_container. It would look like something like this :
template<typename T>
using my_set = boost::multi_index_container<
T,
boost::multi_index::indexed_by<
boost::multi_index::sequenced<>,
boost::multi_index::ordered_unique<boost::multi_index::identity<T>>
>
>;
template<typename T>
T operator[](const my_set &s, const size_t &t){
auto it=s.get<0>.begin();
advance(it, t);
return *it;
}
I tried but I get this error :
error: ‘T operator[](boost::multi_index::multi_index_container<T, boost::multi_index::indexed_by<boost::multi_index::sequenced<>, boost::multi_index::ordered_unique<boost::multi_index::identity<Value> > > >&, int&)’ must be a nonstatic member function
\> &s, int &t){
Is there any way I can do this ?
I want to do this because I had a vector and I need to insert unique elements in it. I used find to know if the element was already in my vector then inserted it if it wasn't. But the linear complexity of find on a vector bothered me, I thought of using a set but I want to keep the elements in the insertion order.
Using a multi_index_container allows me to keep the insertion index with s.get<0> but will also allow me to have unique elements in it
I hope everything's clear.
On first read I thought you wanted to have something like std::map::operator[]
, but that's a bad idea, see below.
On second read I noticed that you ONLY want random-access to the sequenced index. sequenced
has list-like semantics.
You're in luck, random-access indexes already exist! Just use it instead:
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/random_access_index.hpp>
#include <fmt/ranges.h>
namespace bmi = boost::multi_index;
template <typename T>
using my_set = bmi::multi_index_container<
T,
bmi::indexed_by<bmi::random_access<>,
bmi::ordered_unique<bmi::identity<T>>>>;
int main() {
my_set<int> s{1, 7, 7, 8, -4, 22, 1, 5, 4};
fmt::print("Original: {}\n", s);
fmt::print("Same: {}\n", s.get<0>());
fmt::print("Ordered: {}\n", s.get<1>());
fmt::print("Element 2: {}\n", s[2]);
}
Prints:
Original: [1, 7, 8, -4, 22, 5, 4]
Same: [1, 7, 8, -4, 22, 5, 4]
Ordered: {-4, 1, 4, 5, 7, 8, 22}
Element 2: 8
operator[]
is a bad idea"I need to overload the [] operator for boost::multi_index_container" - actually, you don't. You may want to.
Here's why it's not a good idea.
operator[]
on standard associative containers (like std::map
) is not const. It will insert entries if the key isn't found, and will also return a mutable reference to the value.
operator[]
doesn't exist on non-unique standard library containers either! E.g. std::multimap
does not have operator[]
- think about it: which element should be returned?
Boost MultiIndex shares the second reason for not providing these operations. However, regardless of that, all values are always const
in a multi-index container.