Tho*_*ing 6 c++ variadic-templates c++20
是否可以在函数调用站点内交错模板参数?
我实际上想要实现以下内容,但我不知道如何实现(伪代码):
template <size_t... indices, typename... Ts>
void foo(const Things *things)
{
static_assert(sizeof...(indices) == sizeof...(Ts));
constexpr n = sizeof...(Ts);
bar(
indices[0], parse<Ts[0]>(things[0]),
indices[1], parse<Ts[1]>(things[1]),
...
indices[n-1], parse<Ts[n-1]>(things[n-1]));
}
Run Code Online (Sandbox Code Playgroud)
注意:我知道可以执行以下操作(伪代码):
template <size_t... indices, typename... Ts>
void foo(const Things *things)
{
static_assert(sizeof...(indices) == sizeof...(Ts));
constexpr n = sizeof...(Ts);
bar(
indices[0], indices[1], ..., indices[n-1],
parse<Ts[0]>(things[0]),
parse<Ts[1]>(things[1]),
...
parse<Ts[n-1]>(things[n-1]));
}
Run Code Online (Sandbox Code Playgroud)
我想出的部分解决方案是添加一个 swizzling 组件:
template <typename Func>
decltype(auto) swizzle()
{
return Func();
}
template <typename Func, typename T0>
decltype(auto) swizzle(size_t i0, T0 &&t0)
{
return Func(i0, std::forward<T0>(t0));
}
template <typename Func, typename T0, typename T1>
decltype(auto) swizzle(size_t i0, size_t i1, T0 &&t0, T1 &&t1)
{
return Func(i0, std::forward<T0>(t0), i1, std::forward<T1>(t1));
}
Run Code Online (Sandbox Code Playgroud)
但我认为我必须根据我想要考虑的数量手动编写每个案例。
像这样:
template <size_t... indices, typename... Ts>
void foo(const Things *things)
{
std::apply([](auto...args) {
bar(args...);
}, std::tuple_cat(std::make_tuple(indices, parse<Ts>(*(things++)))...));
}
Run Code Online (Sandbox Code Playgroud)
如果bar是 lambda 而不是函数模板,则可以bar直接作为第一个参数传递给std::apply.
如果您想避免复制 的返回值parse<Ts>(*(things++)),可以使用std::forward_as_tuple代替std::make_tuple。
如果让您感到不舒服,一种稍微详细的替代方法*(things++)是使用std::index_sequence:
template <size_t... indices, typename... Ts>
void foo(const Things *things)
{
[=]<auto... Is>(std::index_sequence<Is...>) {
std::apply([](auto...args) {
bar(args...);
}, std::tuple_cat(std::make_tuple(indices, parse<Ts>(things[Is]))...));
}(std::index_sequence_for<Ts...>());
}
Run Code Online (Sandbox Code Playgroud)