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

标签 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; 
}

我无法完全理解这个问题。我开始沿着索引序列的道路前进,但我可以弄清楚如何合并求和。

我使用的是 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... indexestemplate<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/

相关文章:

c++ - 通过 CRTP 的基类引用访问派生类的 constexpr 成员变量

c++ - 为什么我得到零?

c++ - 使用带有可变参数模板函数的 decltype 的尾随返回类型

c++ - 为什么使用统一初始化语法会导致与 "old"样式 () 不同的行为?

c++ - std::cout 在 32/64 位下打印计时持续时间的不同结果

c++ - 受控的应用程序关闭策略

C++如何将来自stdio的输入字符串放入 vector 中,每个容器元素一个字

c++ - 捕获错误并继续返回调用函数

c++ - C++ 中基于枚举值的专用类构造函数

c++ - 如何与私有(private)嵌套类成为 friend