Advertisements
Let’s say I need to make a type that accepts a new types the same way as the containers work.
Can I achieve the same thing without push_back type uses template specialization?
#include <iostream>
template <typename...>
struct type_list {};
template <typename T>
struct my_type { using type = T; };
template <typename LIST, typename T>
struct push_back;
template <typename... Args, typename T>
struct push_back<type_list<Args...>, T> : my_type<type_list<Args..., T>>
{
};
template <typename LIST, typename T>
using push_back_t = typename push_back<LIST, T>::type;
int main()
{
type_list<int, bool> x;
push_back_t<decltype(x), float> y;
type_list<int, bool,float> z;
std::cout << std::is_same_v<decltype(y), decltype(z)> << '\n';
}
>Solution :
You can make it a function template to avoid specialization and make it a bit nicer to use:
template<typename T, typename... Args>
auto push_back(type_list<Args...>) {
return type_list<Args..., T>{};
}
...
auto y = push_back<float>(x);
This is the basis of what Boost.Hana brought to the table for metaprogramming—using empty values whose types contain the desired information. It’s not always this pretty, but it’s surprisingly powerful. Hana is the proof that you can make algorithms fit this format as well, allowing operations like filter
to be implemented with similar levels of ease once you have the groundwork for them.