c ++ 17有效地将参数包参数与std :: array元素相乘 [英] c++17 efficiently multiply parameter pack arguments with std::array elements
问题描述
我想有效地将参数包中的参数与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屋!