Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 是否有任何原因导致c++;使用std::tuple传递模板包_C++_Templates_Tuples_C++14_Variadic Templates - Fatal编程技术网

C++ 是否有任何原因导致c++;使用std::tuple传递模板包

C++ 是否有任何原因导致c++;使用std::tuple传递模板包,c++,templates,tuples,c++14,variadic-templates,C++,Templates,Tuples,C++14,Variadic Templates,假设我们要创建一个帮助器类来反转模板包,例如: #include <tuple> #include <utility> #include <typeinfo> #include <iostream> template <class> struct sizer; template <template<class...> class Pack, class... Args> struct sizer<Pac

假设我们要创建一个帮助器类来反转模板包,例如:

#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;
}
#包括
#包括
#包括
#包括
模板
结构施胶器;
模板
结构筛
那么使用
tuple
对变量进行操作有什么实际原因吗

tuple
不会对其参数执行任何转换,-
tuple
确实包含一个
int[2]
作为其第一个类型,而
void(int[2])
实际上是一个
void(int*)
const
、函数和其他经历衰减的类型也是如此。这使得功能成为不可行的选择

如果您编写了自己的类型列表(例如
template struct typelist{};
),您仍然需要重新实现
std::get
std::tuple\u元素
、和
std::tuple\u size
。这正是tuple的好处所在,它随时可用


每个人都知道什么是
std::tuple
。即使函数签名没有以破坏的方式衰减它们的参数,我仍然会使用创建为异构类型容器的类型,而不是将您的解决方案硬塞进其他碰巧工作的东西中。最小意外原则。

浏览两个代码示例可以显示长度缩短,因为不必重新创建
tuple\u元素。
函数参数类型可能不是数组,而tuple元素类型可能是数组。函数签名是错误的选择。它会调整其参数,例如,函数被调整为函数指针,常量被删除等。您还会使用什么
struct
class
union
不允许您检查其中的类型和数量。有时可以使用
,但这实际上是一个专门的
元组
。开发人员倾向于使用
std::tuple
,因为它附带了一些现成的工具,如
tuple\u元素
。但是,缺点很大:
std::tuple
非常重,创建几十个或100个实例确实会使编译时间陷入困境。@Yakk希望该语言/库会发展到
std::tuple
没有那么重的地步。是否可以将数组存储在具有
tuple
的tuple中?我想你需要
std::array
来做这个。你能解释一下吗?@johanneschaub-litb是的,你能。不过仍然有
tuple
不能很好地处理的类型。
#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;
}