c ++ 17有效地将参数包参数与std :: array元素相乘

Ran*_*its 7 c++ templates c++17

我想有效地将​​参数包中的参数与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; 
}
Run Code Online (Sandbox Code Playgroud)

我无法完全围绕这一个.我开始沿着索引序列前进,但我可以弄清楚如何合并总和.

我使用的是c ++ 17,因此如果简化代码,折叠表达式就是公平的游戏.

谢谢你的任何指示.

编辑:澄清伪代码.唯一的伪部分是Is[i]引用第i个参数包参数的表达式.

TC的答案是完美的,这是我的最终代码,它是一个成员函数:

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

在撰写本文时,代码使用带有-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.
Run Code Online (Sandbox Code Playgroud)

那是我失踪的洞察力.

ken*_*ytm 4

我无法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
}
Run Code Online (Sandbox Code Playgroud)