如何获取函数整数的模板参数包?
How to obtain a template parameter pack of integers int a function?
假设我想要一个像这样的函数:
void reset()
{
(std::get</*pack of integers from 0 to 4*/>(someTuple).reset(), ...);
}
我是用这样的辅助函数完成的:
template < size_t... Indexes >
void reset(std::integer_sequence<size_t, Indexes...>)
{
(std::get<Indexes>(someTuple).reset(), ...);
}
void reset()
{
reset(std::make_integer_sequence<size_t,5>{});
}
但是我可以只用一个功能实现吗?尝试像:
template < size_t... Indexes >
void reset(std::integer_sequence<size_t, Indexes...> = std::make_integer_sequence<size_t,5>{})
{
(std::get<Indexes>(someTuple).reset(), ...);
}
失败,因为调用 reset()
解析为 reset<>(std::integer_sequence<size_t>)
而不是 reset<0,1,2,3,4>(std::integer_sequence<size_t,0,1,2,3,4>)
。我使用的是 GCC-7.0.0
的最新快照
您可以像这样使用通用 lambda 和一些辅助结构:
#include <utility>
#include <type_traits>
#include <tuple>
template <std::size_t N, class = std::make_index_sequence<N>>
struct iterate;
template <std::size_t N, std::size_t... Is>
struct iterate<N, std::index_sequence<Is...>> {
template <class Lambda>
void operator()(Lambda lambda) {
lambda(std::integral_constant<std::size_t, Is>{}...);
}
};
struct Foo {
void reset() {}
};
void reset() {
std::tuple<Foo, Foo, Foo> bar;
iterate<std::tuple_size<decltype(bar)>::value>{}([&](auto... is) {
(std::get<is>(bar).reset(), ...);
});
}
int main() {
reset();
}
您可以使用默认的模板参数实现类似的效果:
template <class S = std::make_index_sequence<5>>
struct reset; // intentionally undefined
template <size_t... Is>
struct reset<std::index_sequence<Is...>> {
template <class Tuple>
static void impl(Tuple& t) {
(std::get<Is>(t).reset(), ...);
}
};
reset<>::impl(someTuple);
但不是在函数中(因为这样的事情需要函数模板的部分特化,而语言不支持)。
相反,只需为内联参数包解包创建一个辅助 lambda:
void reset() {
indexer<5>()([&](auto I){
std::get<I>(someTuple).reset();
});
}
假设我想要一个像这样的函数:
void reset()
{
(std::get</*pack of integers from 0 to 4*/>(someTuple).reset(), ...);
}
我是用这样的辅助函数完成的:
template < size_t... Indexes >
void reset(std::integer_sequence<size_t, Indexes...>)
{
(std::get<Indexes>(someTuple).reset(), ...);
}
void reset()
{
reset(std::make_integer_sequence<size_t,5>{});
}
但是我可以只用一个功能实现吗?尝试像:
template < size_t... Indexes >
void reset(std::integer_sequence<size_t, Indexes...> = std::make_integer_sequence<size_t,5>{})
{
(std::get<Indexes>(someTuple).reset(), ...);
}
失败,因为调用 reset()
解析为 reset<>(std::integer_sequence<size_t>)
而不是 reset<0,1,2,3,4>(std::integer_sequence<size_t,0,1,2,3,4>)
。我使用的是 GCC-7.0.0
您可以像这样使用通用 lambda 和一些辅助结构:
#include <utility>
#include <type_traits>
#include <tuple>
template <std::size_t N, class = std::make_index_sequence<N>>
struct iterate;
template <std::size_t N, std::size_t... Is>
struct iterate<N, std::index_sequence<Is...>> {
template <class Lambda>
void operator()(Lambda lambda) {
lambda(std::integral_constant<std::size_t, Is>{}...);
}
};
struct Foo {
void reset() {}
};
void reset() {
std::tuple<Foo, Foo, Foo> bar;
iterate<std::tuple_size<decltype(bar)>::value>{}([&](auto... is) {
(std::get<is>(bar).reset(), ...);
});
}
int main() {
reset();
}
您可以使用默认的模板参数实现类似的效果:
template <class S = std::make_index_sequence<5>>
struct reset; // intentionally undefined
template <size_t... Is>
struct reset<std::index_sequence<Is...>> {
template <class Tuple>
static void impl(Tuple& t) {
(std::get<Is>(t).reset(), ...);
}
};
reset<>::impl(someTuple);
但不是在函数中(因为这样的事情需要函数模板的部分特化,而语言不支持)。
相反,只需为内联参数包解包创建一个辅助 lambda:
void reset() {
indexer<5>()([&](auto I){
std::get<I>(someTuple).reset();
});
}