使用std :: tuple传递c ++模板包有什么原因吗? [英] Are there any reasons why c++ template packs are passed using std::tuple
问题描述
假设我们要创建一个帮助类来反向模板包。如下:
Let's say we want to create a helper class to reverse template pack e.g. as follows:
#include <tuple>
#include <utility>
#include <typeinfo>
#include <iostream>
template <class>
struct sizer;
template <template<class...> class Pack, class... Args>
struct sizer<Pack<Args...>> {
static constexpr size_t value = sizeof...(Args);
};
template <class Pack, class Indices = std::make_index_sequence<sizer<Pack>::value>>
struct reverse_pack;
template <class... Args, size_t... I>
struct reverse_pack<std::tuple<Args...>, std::integer_sequence<std::size_t, I...>> {
using type = typename std::tuple<typename std::tuple_element<(sizeof...(Args) - I - 1), std::tuple<Args...>>::type...>;
};
int main() {
std::cout << typeid(reverse_pack<std::tuple<int, float, double>>::type).name() << std::endl;
}
我们可以使用函数签名作为模板参数:
We could successfully do exactly the same thing using e.g. function signature as a template parameter:
#include <utility>
#include <typeinfo>
#include <iostream>
template <class>
struct sizer;
template <class... Args>
struct sizer<void(Args...)> {
static constexpr size_t value = sizeof...(Args);
};
template <size_t N, class Sign>
struct nth_param;
template <size_t N, class First, class... Args>
struct nth_param<N, void(First, Args...)>: nth_param<N-1, void(Args...)> { };
template <class First, class... Args>
struct nth_param<0, void(First, Args...)> {
using type = First;
};
template <class Pack, class Indices = std::make_index_sequence<sizer<Pack>::value>>
struct reverse_pack;
template <class... Args, size_t... I>
struct reverse_pack<void(Args...), std::integer_sequence<std::size_t, I...>> {
using type = void(typename nth_param<(sizeof...(Args) - I - 1), void(Args...)>::type...);
};
int main() {
std::cout << typeid(reverse_pack<void(int, float, double)>::type).name() << std::endl;
}
我在使用 std :: tuple
(例如这里)显示它打算存储数据,而不是在模板之间传递类型包。因此,有什么实际的理由使用元组来操作可变参数吗?
My experience with std::tuple
(e.g. here) shows its intended to store data rather than to pass packs of types between template. So are there any practical reasons to use a tuple to operate on variadics?
推荐答案
使用
元组
操作可变参数的任何实际原因?
So are there any practical reasons to use a
tuple
to operate on variadics?
code> tuple 不会对其参数执行任何转换 - tuple< int [2]>
确实包含 int [2]
作为它的第一个类型,而 void(int [2])
> void(int *)。这同样适用于 const
,函数和其他经历衰减的类型。这使得功能成为不可行的选择。
A tuple
doesn't perform any conversions on its arguments - a tuple<int[2]>
indeed contains an int[2]
as its first type, whereas a void(int[2])
is really a void(int*)
. The same holds for const
, functions, and other types that undergo decay. That makes function a non-viable option.
如果您编写了自己的类型串(例如 template< class ... Ts> struct typelist {};
),你仍然必须重新实现 std :: get
, std :: tuple_element
和 std :: tuple_size
。这是 tuple
的好处,它已经准备就绪并且实用。
If you wrote your own typelist (e.g. template <class... Ts> struct typelist{};
), you would still have to reimplement std::get
, std::tuple_element
, and std::tuple_size
. That's the nice thing about tuple
- it comes ready and useful.
每个人都知道 std :: tuple
是。即使函数签名没有以破坏的方式衰减它们的参数,我仍然会使用创建的类型是类型的异构容器 - 而不是将你的解决方案带到正在发生的其他事情。最起码的惊喜和所有的原则。
And everybody already knows what std::tuple
is. Even if function signatures didn't decay their arguments in a way that would break, I would still use the type that's created to be a heterogeneous container of types - and not shoehorn your solution into something else that happens to work. Principle of least surprise and all.
这篇关于使用std :: tuple传递c ++模板包有什么原因吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!