My question is about this code:
auto& lookup = container.template get<1>();
container.relocate(container.begin(),container.template project<0>(it));
1st: .template
From what I've found, this template keyword specified on my container is using a template, correct me if I'm wrong.
src: (Where and why do I have to put the "template" and "typename" keywords?)
2nd: project<0>(it)
Looking for the definition in the lib, I saw that it needed an iterator as a parameter, but I don't understand the project<0>
(same for get<1>
).
I found some information like this: https://theboostcpplibraries.com/boost.variant, and posts on Stack Overflow too, but I'm a little bit confused.
CodePudding user response:
As explained here, in both cases you need the template
keywords because container::project
and container::get
are (presumably-- we do not have the code here) template member functions. To instantiate them you need to specify the template parameter. But, as detailed in the linked answer, the compiler would not understand a code like
container.project<0>(it)
and needs the template
keyword as in your code.
CodePudding user response:
You are right about the reason why template
can be required. Note it is only required in dependent context (where the actual specialization of a template may depend on template parameters).
The documentation is here
:
Indices are accessed via
get<N>()
where
N
ranges between 0 and the number of comparison predicates minus one. The functionality of index #0 can be accessed directly from amulti_index_container
object without usingget<0>()
: for instance,es.begin()
is equivalent toes.get<0>().begin()
.Note that get returns a reference to the index, and not an index object. Indices cannot be constructed as separate objects from the container they belong to, so the following
// Wrong: we forgot the & after employee_set::nth_index<1>::type const employee_set::nth_index<1>::type name_index=es.get<1>();
does not compile, since it is trying to construct the index object
name_index
. This is a common source of errors in user code.-
Given indices
i1
andi2
on the samemulti_index_container
,project
can be used to retrieve an i2-iterator from an i1-iterator, both of them pointing to the same element of the container. This functionality allows the programmer to move between different indices of the same multi_index_container when performing elaborate operations:typedef employee_set::index<name>::type employee_set_by_name; employee_set_by_name& name_index=es.get<name>(); // list employees by ID starting from Robert Brown's ID employee_set_by_name::iterator it1=name_index.find("Robert Brown"); // obtain an iterator of index #0 from it1 employee_set::iterator it2=es.project<0>(it1); std::copy(it2,es.end(),std::ostream_iterator<employee>(std::cout));