有人可以解释一下“指数骗局”吗? [英] Can someone please explain the "indices trick"?

查看:182
本文介绍了有人可以解释一下“指数骗局”吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我注意到在pretty-print元组的上下文中提到的indices trick。听起来很有趣,所以我按照链接



嗯,那不顺利。我理解这个问题,但真的不能跟随发生了什么。为什么我们甚至需要任何索引?那里定义的不同功能如何帮助我们?什么是裸?



有人可以为参数包和可变元组中少于专家的玩家播放该游戏吗?

解决方案

问题是:我们有一个 std :: tuple< T1,T2,...> 并且我们有一些函数 f ,我们可以调用每个元素,其中 f 返回 int ,我们要将这些结果存储在数组中。



让我们从一个具体案例开始:

  T> int f(T){return sizeof(T); } 

std :: tuple< int,char,double> tup {42,'x',3.14};
std :: array< int,3> arr {f(std :: get'(tup)),
f(std :: get'(tup)),
f(std :: get& ;

除了写出所有 get 不方便和冗余,在最坏的情况下容易出错。现在,假设我们有一个类型 index_sequence< 0,1,2> 。我们可以使用它将数组初始化折叠成一个可变包扩展:

  template< typename Tuple,size_t ... Indices> ; 
std :: array< int,sizeof ...(Indices)>
call_f_detail(Tuple& tuple,index_sequence< Indices ...>){
return {f(std :: get< Indices>(tuple))...}这是因为在函数中, f(std:


$ b < :get< Indices>(tuple))...
得到扩展为 f(std :: get< 0>(tuple)),f(std :: get< 1> ;(tuple)),f(std :: get 2(tuple))。这正是我们想要的。



问题的最后一个细节只是生成特定的索引序列。 C ++ 14实际上为我们提供了一个名为 make_index_sequence

  template< typename Tuple> 
std :: array< int,std :: tuple_size< Tuple> :: value>
call_f(Tuple& tuple){
return call_f_detail(tuple,
// make the sequence type sequence< 0,1,2,...,N-1>
std :: make_index_sequence< std :: tuple_size< Tuple> :: value> {}
);
}

,而你链接的文章只是解释如何实现这样的元功能。



可能是 Luc Danton的回答

 模板< typename T& 
using Bare = typename std :: remove_cv< typename std :: remove_reference< T> :: type> :: type;


I noticed the "indices trick" being mentioned in the context of pretty-printing tuples. It sounded interesting, so I followed the link.

Well, that did not go well. I understood the question, but could really not follow what was going on. Why do we even need indices of anything? How do the different functions defined there help us? What is 'Bare'? etc.

Can someone give a play-by-play of that thing for the less-than-experts on parameter packs and variadic tuples?

解决方案

The problem is: we have a std::tuple<T1, T2, ...> and we have some function f that we can to call on each element, where f returns an int, and we want to store those results in an array.

Let's start with a concrete case:

template <typename T> int f(T ) { return sizeof(T); }

std::tuple<int, char, double> tup{42, 'x', 3.14};
std::array<int, 3> arr{ f(std::get<0>(tup)), 
                        f(std::get<1>(tup)),
                        f(std::get<2>(tup)) );

Except writing out all those gets is inconvenient and redundant at best, error-prone at worst. Now, let's say we had a type index_sequence<0, 1, 2>. We could use that to collapse that array initialization into a variadic pack expansion:

template <typename Tuple, size_t... Indices>
std::array<int, sizeof...(Indices)> 
call_f_detail(Tuple& tuple, index_sequence<Indices...> ) {
    return { f(std::get<Indices>(tuple))... };
}

That's because within the function, f(std::get<Indices>(tuple))... gets expanded to f(std::get<0>(tuple)), f(std::get<1>(tuple)), f(std::get<2>(tuple)). Which is exactly what we want.

The last detail of the problem is just generating that particular index sequence. C++14 actually gives us such a utility named make_index_sequence

template <typename Tuple>
std::array<int, std::tuple_size<Tuple>::value>
call_f(Tuple& tuple) {
    return call_f_detail(tuple,
        // make the sequence type sequence<0, 1, 2, ..., N-1>
        std::make_index_sequence<std::tuple_size<Tuple>::value>{}
        );
}

whereas the article you linked simply explains how one might implement such a metafunction.

Bare is probably something like, from Luc Danton's answer:

template<typename T>
using Bare = typename std::remove_cv<typename std::remove_reference<T>::type>::type;

这篇关于有人可以解释一下“指数骗局”吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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