使用模板折叠表达式而不是函数模板的递归实例?
use template fold expressions instead of recursive instantions of a function template?
给定一个可变参数包,我想用包中的每个元素及其索引调用一个函数。
我在下面有一个简单的例子,它使用函数模板的递归实例来实现这一点。 (on godbolt)
#include <iostream>
#include <tuple>
template<std::size_t I, typename Tuple>
void foo(Tuple&& tuple)
{
std::cout << "item " << I << "=" << std::get<I>(tuple) << '\n';
if constexpr (I + 1 < std::tuple_size_v<std::decay_t<Tuple>>)
foo<I+1>(tuple);
}
template<typename... Ts>
void bar(Ts... ts)
{
foo<0>(std::tuple(ts...));
}
int main()
{
bar(5, 3.14, "hello world", 'c');
return 0;
}
这按预期工作:
item 0=5
item 1=3.14
item 2=hello world
item 3=c
是否可以使用 std::index_sequence
和模板折叠表达式获得相同的结果?
可能是:
template<size_t ... Indices, typename... Ts>
void bar2(std::index_sequence<Indices...>, Ts&&... ts) {
auto action = [](size_t idx, auto&& arg) { std::cout << "item " << idx << "=" << arg << std::endl; };
(action(Indices,std::forward<Ts>(ts)),...);
}
template<typename... Ts>
void bar2(Ts&&... ts) {
bar2(std::make_index_sequence<sizeof...(Ts)>(), std::forward<Ts>(ts)...);
}
无需使用std::index_sequence
#include <iostream>
template<typename... Ts>
void bar(Ts&&... ts) {
std::size_t idx = 0;
((std::cout << "item " << idx++ << "=" << ts << '\n'), ...);
}
如果你想让I
成为一个non-type模板参数,那么一个模板lambda就足够了
template<typename... Ts>
void bar(Ts&&... ts) {
[&]<std::size_t... Is>(std::index_sequence<Is...>) {
((std::cout << "item " << Is << "=" << ts << '\n'), ...);
}(std::index_sequence_for<Ts...>{});
}
给定一个可变参数包,我想用包中的每个元素及其索引调用一个函数。
我在下面有一个简单的例子,它使用函数模板的递归实例来实现这一点。 (on godbolt)
#include <iostream>
#include <tuple>
template<std::size_t I, typename Tuple>
void foo(Tuple&& tuple)
{
std::cout << "item " << I << "=" << std::get<I>(tuple) << '\n';
if constexpr (I + 1 < std::tuple_size_v<std::decay_t<Tuple>>)
foo<I+1>(tuple);
}
template<typename... Ts>
void bar(Ts... ts)
{
foo<0>(std::tuple(ts...));
}
int main()
{
bar(5, 3.14, "hello world", 'c');
return 0;
}
这按预期工作:
item 0=5 item 1=3.14 item 2=hello world item 3=c
是否可以使用 std::index_sequence
和模板折叠表达式获得相同的结果?
可能是:
template<size_t ... Indices, typename... Ts>
void bar2(std::index_sequence<Indices...>, Ts&&... ts) {
auto action = [](size_t idx, auto&& arg) { std::cout << "item " << idx << "=" << arg << std::endl; };
(action(Indices,std::forward<Ts>(ts)),...);
}
template<typename... Ts>
void bar2(Ts&&... ts) {
bar2(std::make_index_sequence<sizeof...(Ts)>(), std::forward<Ts>(ts)...);
}
无需使用std::index_sequence
#include <iostream>
template<typename... Ts>
void bar(Ts&&... ts) {
std::size_t idx = 0;
((std::cout << "item " << idx++ << "=" << ts << '\n'), ...);
}
如果你想让I
成为一个non-type模板参数,那么一个模板lambda就足够了
template<typename... Ts>
void bar(Ts&&... ts) {
[&]<std::size_t... Is>(std::index_sequence<Is...>) {
((std::cout << "item " << Is << "=" << ts << '\n'), ...);
}(std::index_sequence_for<Ts...>{});
}