我想有效地将参数包中的参数与 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;
}
我无法完全理解这个问题。我开始沿着索引序列的道路前进,但我可以弄清楚如何合并求和。
我使用的是 c++17,所以如果折叠表达式可以简化代码,那么折叠表达式是公平的游戏。
感谢您的指点。
编辑:澄清了伪代码。唯一的伪部分是表达式 Is[i]
它指的是第 i 个参数包参数。
下面 T.C. 的回答是完美的,这是我的最终代码,它是一个成员函数:
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。
使用 auto... indexes
是 template<typename Args> f(Args... indexes)
的简写.我尝试对参数使用 unsigned int 概念,但我无法让它工作。
(...,) 折叠是关键元素并扩展为类似的东西(如果您实际上可以 [] 进入参数包):
idx += indexes[0] * m_strides[i++], idx += indexes[1] * m_strides[i++], etc.
那是我所缺少的洞察力。
最佳答案
我无法让 auto...
工作,所以我更改了 index
的签名。
您将需要一个辅助函数(此处为 index_helper
)来使用 index_sequence
,因为它依赖于模板参数推导来填充索引。
#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 元素相乘,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42849675/