c ++ 17有效地将参数包参数与std :: array元素相乘 [英] c++17 efficiently multiply parameter pack arguments with std::array elements

查看:53
本文介绍了c ++ 17有效地将参数包参数与std :: array元素相乘的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想有效地将​​参数包中的参数与std :: array:的元素相乘.

I want to efficiently multiply the arguments from a parameter pack with the elements of a std::array:

int index(auto... Is, std::array<int,sizeof...(Is)> strides)
{
  // pseudo-code
  // int idx = 0;
  // for(int i = 0; i < sizeof...(Is); ++i)
  //   idx += Is[i] * strides[i];
  // return idx; 
}

我不能完全包绕这个大脑.我从索引序列的道路上开始,但是我可以弄清楚如何合并求和.

I can't quite wrap my brain around this one. I started down the road of an index sequence, but I could figure out how to incorporate the summation.

我使用的是c ++ 17,因此如果fold表达式可以简化代码,则它们是公平的游戏.

I am using c++17, so fold expressions are fair game if they would simplify the code.

感谢任何指针.

澄清了伪代码.唯一的伪部分是表达式 Is [i] ,它表示第i个参数包参数.

Clarified the pseudo-code. The only pseudo part is the expression Is[i] which refers to the i'th parameter pack argument.

以下T.C.的答案很完美,这是我的最终代码,它是成员函数:

T.C.'s answer below was perfect and here is my final code which is a member function:

unsigned int index(auto... indexes)
{
    unsigned int idx = 0, i = 0;
    (..., (idx += indexes * m_strides[i++]));
    return idx;
}

在撰写本文时,代码使用带有-fconcepts标志的gcc 6.3.0进行编译,该标志引入了Concept TS.

As of this writing, the code compiles using gcc 6.3.0 with the -fconcepts flag, which brings in the Concept TS.

使用 auto ...索引 template< typename Args>的简写.f(Args ... indexs).我尝试对参数使用unsigned int概念,但无法正常工作.

Using auto... indexes is shorthand for template<typename Args> f(Args... indexes). I tried to use an unsigned int concept for the arguments, but I couldn't get that to work.

(...,)折叠是关键元素,它会扩展为类似的内容(如果您实际上可以将[]放入参数包中):

The (...,) fold is the key element and expands to something like (if you could actually [] into the parameter pack):

idx += indexes[0] * m_strides[i++], idx += indexes[1] * m_strides[i++], etc.

那是我所缺少的见解.

推荐答案

我无法使 auto ... 正常工作,所以我更改了 index 的签名.

I can't get auto... to work, so I changed the signature of index.

您将需要一个辅助函数(此处为 index_helper )来使用 index_sequence ,因为它依赖模板参数推导来填充索引.

You will need an auxiliary function (index_helper here) to use index_sequence, since it relies on template argument deduction to fill in the indices.

#include <array>
#include <cstdio>

template <typename... T, size_t... i>
//                       ^~~~~~~~~~~
//                        use deduction to make {i...} = {0, 1, 2, ..., n}
static int index_helper(const std::array<int, sizeof...(T)>& strides,
                        std::index_sequence<i...>,
                        T... Is) 
{
    return (0 + ... + (strides[i] * Is));
}

template <typename... T>
int index(const std::array<int, sizeof...(T)>& strides, T... Is) {
    return index_helper(strides, std::make_index_sequence<sizeof...(T)>(), Is...);
//                               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//                                generates {0, 1, 2, ..., n}
}

int main() {
    printf("%d\n", index({1, 100, 100000, 1000}, 2, 3, 5, 7));
    // 507302
}

这篇关于c ++ 17有效地将参数包参数与std :: array元素相乘的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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