G. *_*dam 2 c++ templates variadic-templates
我很喜欢学习元编程,并开始了解一些功能,但我无法调用 at Works,它需要一个索引来返回映射到可变位置的类型。
#include <iostream>
#include <type_traits>
#include <utility>
template <typename...>
struct type_list {};
template<typename T ,typename... Ns>
auto pop_front(type_list<T, Ns...> t) {
return type_list<Ns...>{};
}
template<typename T ,typename... Ns>
auto front(type_list<T, Ns...> t)
{
return type_list<T>{};
}
template<typename T ,typename... Ns>
auto at(type_list<T, Ns...> t, size_t i)
{
if (i) return at(pop_front(t), i-1);
return front(t);
}
int main()
{
type_list<int, bool, float> x;
at(x,2);
}
Run Code Online (Sandbox Code Playgroud)
如果我们将索引移动到模板参数中,使其成为编译时常量,那么我们可以利用std::tuple_element提供的索引来获取类型,例如
template<size_t Idx, typename... Ts>
auto at(type_list<Ts...>)
{
return std::tuple_element_t<Idx, std::tuple<Ts...>>{};
}
Run Code Online (Sandbox Code Playgroud)
然后我们可以这样称呼它
at<2>(x);
Run Code Online (Sandbox Code Playgroud)
It should be noted that this approach requires all types in the list to be default constructible.
If you are only ever going to use at in a context like decltype(at<2>(x)) then you actually don't need to define the function and can instead use what I call a "meta function" like
template<size_t Idx, typename... Ts>
auto at(type_list<Ts...>t) -> std::tuple_element_t<Idx, std::tuple<Ts...>>;
Run Code Online (Sandbox Code Playgroud)
and now you can't run this function, but you can use it an any unevaluated context, like in decltype(at<2>(x)), and the types in the list do not need to be default constructible.