I am reading a blog about building a custom heterogeneous container in C++. In the blog, the author used visitor pattern to print out each element of the container ordered by their types. I'm wondering if it is possible for me to write a visitor such that I could print out the elements in the order they were inserted?
As you store element by type, you loose insertion order, so you have to change
template<class T>
static std::unordered_map<const heterogeneous_container*, std::vector<T>> items;
by
template <class T>
static std::unordered_map<const heterogeneous_container*,
std::vector<std::pair<std::size_t, T>>> items;
Add a visit_ordered:
template <typename T, class V>
void visit_with_index_impl_help(V& visitor)
{
for (auto&& p : items<T>[this])
{
visitor(p.first, p.second);
}
}
template <class V, typename... Ts>
void visit_ordered_impl(V& visitor, type_list<Ts...>)
{
std::vector<std::pair<std::size_t, std::function<void()>> funcs;
const auto inserter = [&](std::size_t i, auto&& elem) {
funcs.emplace_back(i, visitor(elem));
};
(..., visit_with_index_impl_help<Ts>(inserter));
const auto less_by_first = [](const auto& lhs, const auto& rhs){ return lhs.first < rhs.first; };
std::sort(funcs.begin(), funcs.end(), less_by_first);
for (auto&& func : funcs) {
func();
}
}
template <class V>
void visit_ordered(V& visitor)
{
visit_ordered_impl(visitor, typename std::decay_t<V>::types{})
}