C++17 有效地将参数包参数与 std::array 元素相乘
c++17 efficiently multiply parameter pack arguments with std::array elements
我想有效地将参数包中的参数与 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;
}
在撰写本文时,代码使用 gcc 6.3.0 和 -fconcepts 标志进行编译,该标志引入了概念 TS。
使用auto... indexes
是template<typename Args> f(Args... indexes)
的简写。我试图使用一个无符号的 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("%dn", index({1, 100, 100000, 1000}, 2, 3, 5, 7));
// 507302
}
如果你能把参数包敲定成一个复制/移动成本低的单一类型,你可以把它变成一个数组:
T arr[] = { static_cast<T>(Is)... }; // for some T, possibly common_type_t<decltype(Is)...>
然后,您可以将伪代码转换为真实代码。
如果这不可行,可以使用逗号折叠:
int idx = 0, i = 0;
(..., (idx += Is * strides[i++]));
return idx;
相关文章:
- 带有指定长度字符* 参数的 std::regex_search 在 VS2017 中不起作用?
- 为什么 std::function 可以作为 std::not2 的参数?
- 传递给std::function template的template参数究竟代表什么
- 转换函数,将 std::数组的双精度作为参数或双精度作为参数单独转换
- 在C++中,使用带有 std::optional 参数的函数<T>来表示可选参数是否有意义?
- 将函数参数"const char*"转换为"std::string_view"是
- 当指向对象的指针作为参数传递给 std::thread 时,内存可见性
- 为什么 std::绑定错误参数可以成功?
- 使用模板化的键类型定义 std::map,该键类型基于作为参数接收的函数
- std::vector 没有重载函数的实例与参数列表匹配
- std::span<const T> 作为函数模板中的参数
- SegFault 同时使用 std::string::operator+= 和函数作为参数
- 如果模板没有可变参数,则 Lambda 被推导出为 std::function
- 将参数打包的参数传递到 std::queue 中,以便稍后使用不同的函数调用
- 在构造函数中使用可变参数初始化 std::tuple
- 函数对象无法识别它获得的参数(std::set<int>)
- C 11构造函数参数:std ::移动和值或std :: forward and rvalue参考
- std::move 或 std::forward 参数 std::unique_ptr&<T>&
- 错误:不允许使用"C++/ObjC++"使用无效参数"-std=gnu99"
- **编译器错误** - getline() 函数不接受第一个参数"std:ifstream"是什么我的问题?