使用std :: tuple传递c ++模板包有什么原因吗? [英] Are there any reasons why c++ template packs are passed using std::tuple

查看:231
本文介绍了使用std :: tuple传递c ++模板包有什么原因吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我们要创建一个帮助类来反向模板包。如下:

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆