Use boost::container or boost::recursive_wrapper for creating containers of incomplete types
-
14-07-2021 - |
質問
I need to create a structure that has a vector<self>
as a member variable. Boost offers 2 mechanisms that achieve this:
1 - using boost::recursive_wrapper
i.e.:
struct filter
{
uint32_t id;
std::vector< boost::recursive_wrapper< filter > > childFilters;
};
2 - using boost::container
i.e.:
struct filter
{
uint32_t id;
boost::container::vector< filter > childFilters;
};
Is there any advantage with each technique? The second boost::container
option involves less syntax, and I guess it uses a technique similar to the boost::recursive_wrapper
internally.
解決
The better choice is to use boost::container::vector
, because it allows direct access to the type stored in the vector.
The extra layer of indirection provided by boost::recursive_wrapper
that allows the declaration of a std::vector<self>
makes code manipulating the vector more cumbersome, because it is necessary get
to access the actual type being held.
i.e.
struct filter
{
uint32_t id;
std::vector< boost::recursive_wrapper< filter > > childFilters;
};
filter myFilter;
// fill myFilter .....
BOOST_FOREACH( boost::recursive_wrapper< filter > f, myFilter.childFilters )
{
std::cout << f.get().id << "\n";
}
With boost::container::vector
the example becomes:
struct filter
{
uint32_t id;
boost::container::vector< filter > childFilters;
};
filter myFilter;
// fill myFilter .....
BOOST_FOREACH( boost::recursive_wrapper< filter > f, myFilter.childFilters )
{
std::cout << f.id << "\n"; // no call to get()
}