我很难将std::数组的参数包展开并转发到另一个函数
假设我们有一个函数,它包含一个std::数组,我想要展开它,并将它作为参数传递给其他函数,我可以这样做:
template<typename T, typename...Ts>
void other_function(T, Ts...) { /* Do stuff with Ts */ }
template<typename T, size_t Size, size_t... I>
void forward_array(std::array<T, Size>& array_arg, std::index_sequence<I...>)
{
other_function(array_arg[I]...);
// for Size == 3 let's say we get the same thing as we would write
// other_function(array_arg[0], array_arg[1], array_arg[2]
// I skipped the std::forward
}
现在让我们假设我们有一个函数做同样的事情,但是它需要多个不同大小的数组。
template<typename T, size_t... Sizes /*, size_t... I_Sequence0, size_t... I_Sequence1, ... I_SequenceN */>
void forward_many_arrays(std::array<T, Sizes>&... array_args /*, ???*/)
{
other_func( /* ??? */);
}
我想展开每个array_arg并将其传递给other_func,但是在这里我要如何准确地做到这一点呢?。 我们需要一种方法来索引每个数组参数。
在我的实际程序中,我有一个类,它的成员std::array是std::reference_wrapper,它不是默认可构造的,我试图为这个类提供一个替代构造函数,它接受任意数量的数组,其中数组大小之和匹配成员数组大小,并将它委托给接受T个引用的显式构造函数,但是我有点卡在那里,因为我不知道如何处理展开。
你可能有一个“通用的”getter
template <std::size_t I, typename Container, typename ... Containers>
decltype(auto) get(Container&& container, Containers&&...containers)
{
constexpr std::size_t size = std::tuple_size_v<std::decay_t<Container>>;
if constexpr (I < size) {
return container[I];
} else {
return get<I - size>(containers...);
}
}
如:
template <typename...Ts>
void other_function(Ts... ts) { ((std::cout << ts << " "), ...); }
template<typename... Ts, size_t... Is>
void forward_many_arrays(std::index_sequence<Is...>, Ts&&...ts)
{
other_function(get<Is>(ts...)...);
}
template<typename... Ts>
void forward_many_arrays(Ts&&...ts)
{
forward_many_arrays(std::make_index_sequence<(std::tuple_size_v<std::decay_t<Ts>> + ...)>(), ts...);
}
演示
一种基于简单递归的实现;
template<std::size_t n, class Fn, class T, class... Ts>
void apply_all_impl(Fn fn, T& t, Ts&... ts) {
if constexpr (n == 0)
fn(t, ts...);
else
std::apply([&](auto&... args) {
apply_all_impl<n - 1>(fn, ts..., args...);
}, t);
}
template<class Fn, class... Ts>
void apply_all(Fn fn, Ts&... ts) {
apply_all_impl<sizeof...(Ts)>(fn, ts...);
}
用法示例:
std::array<int, 3> arr1{1, 2, 3};
std::array<int, 4> arr2{4, 5, 6, 7};
auto print_all = [](auto... ts) { (std::cout << ... << ts); };
apply_all(print_all, arr1, arr2); // Output: 1234567
演示