C++:转发参数包和std::tuple/数组的和
C++: Forwarding the sum of parameter pack and a std::tuple/array
我想实现类似以下成员函数(方法)的东西,它应该将每个参数增加一些与参数索引相对应的被加数(addend),并将其转发到另一个可变模板函数:
template<typename... Int> // a bunch of integral types (e.g. int, size_t, char)
void ForwardToFuncIncreased(Int... ints) {
static_assert(sizeof...(Ints) == std::tuple_size<decltype(summands_)>::value,
"Incorrect number of integral types provided");
Func( (ints + std::get<PARAM_INDEX(ints)>(summands_))... ); // failed attempt
}
其中summands_
是类型为std::tuple
或std::array
的成员变量(您可以假设两者之一)。基本要求是,与相比,它应该没有运行时开销
Func(int0 + std::get<0>(summands_), int1 + std::get<1>(summands_), ...);
(假设我为N
模板参数重载了函数)。
如果在没有必要的运行时开销的情况下无法做到这一点,我愿意进行某些修改(特别是在类中存储额外的东西或修改类型的方式)。
注意:我的意图不是提取模板参数索引,而是希望在没有它的情况下实现我所需要的。
在C++14中,您将能够执行以下操作,与您最初的尝试非常相似:
template<typename... Ns, size_t... Is>
void ForwardToFuncIncreasedImpl(Ns... nums, std::index_sequence<Is...>)
{
Func( (nums + std::get<Is>(summands_))... );
}
template<typename... Ns>
void ForwardToFuncIncreased(Ns... nums)
{
ForwardToFuncIncreasedImpl(nums..., std::index_sequence_for<Ns...>());
}
同时,您可以找到或编写自己的index_sequence
实现。
或者这样做:首先做std::make_tuple(ints...)
,这样我们就有两个要求和的元组(或者一个元组和一个std::array
)。然后使用Andrei Alexandrescu在《爆炸元组的方式》中演示的模式,将和展开为参数包,并将其传递给Func
。
template <int N>
struct Pairwise;
template <>
struct Pairwise<0>
{
template <typename F, typename T, typename U, typename... Args>
static void Sum(F f, T const&, U const&, Args... sums)
{
f(sums...);
}
};
template <int N>
struct Pairwise
{
template <typename F, typename T, typename U, typename... Args>
static void Sum(F f, T const& a, U const& b, Args... sums)
{
Pairwise<N - 1>::Sum(f, a, b, std::get<N - 1>(a) + std::get<N - 1>(b), sums...);
}
};
template <typename... Ns>
void ForwardToFuncIncreased(Ns... nums)
{
Pairwise<sizeof...(Ns)>::Sum(Func, std::make_tuple(nums...), summands_);
}
也可以在没有初始make_tuple
:的情况下进行
template <typename... Ns>
struct Pairwise;
template <>
struct Pairwise<>
{
template <typename F, typename T, typename... Args>
static void Sum(F f, T const&, Args... sums)
{
f(sums...);
}
};
template <typename N0, typename... Ns>
struct Pairwise<N0, Ns...>
{
template <typename F, typename T, typename... Args>
static void Sum(F f, N0 num0, Ns... nums, T const& a, Args&&... sums)
{
Pairwise<Ns...>::Sum(f, nums..., a, sums..., num0 + std::get<sizeof...(Args)>(a));
}
};
template <typename... Ns>
void ForwardToFuncIncreased(Ns... nums)
{
Pairwise<Ns...>::Sum(Func, nums..., summands_);
}
相关文章:
- Mongodb c++驱动程序:如何查询元素的数组
- 将数组的地址分配给变量并删除
- 从C++本机插件更新Vector3数组
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 数组索引的值没有增加
- 将对象数组的引用传递给函数
- 为char数组调整zlib-zpipe
- 2D数组来自文本输入,中间有空格
- std::向量与传递值的动态数组
- 在c++中用vector填充一个简单的动态数组
- 使用strcpy将char数组的元素复制到另一个数组
- 使用指针从C++中的数组中获取最大值
- C++使用整数的压缩数组初始化对象
- 告诉一个 const char 数组,除了编译时 C 样式的字符串外,它不以 '