我想写一个函数write
,它可以接受任何类型的多个参数,并将它们打印到stdout
。但我也希望传入一个分隔符作为最后一个参数。
template <typename... T>
void write(T &&...args, string delimiter) { // compilation error
((cout << args << delimiter),...);
}
用法:
write(1, ""); // single element with empty delimeter
write(1, "one", " "); // space as delimeter
write(1, "one", ","); // comma as delimeter
现在,自动类型推导失败了,因为C++希望参数包是最后一个参数。
我怎样才能做到这一点?
这篇博客文章中有一个很好的技巧可以使用。
修改write
以仅接受参数包
template <typename... Ts>
void write(Ts && ...args)
{
write_indirect(std::forward_as_tuple(args...),
std::make_index_sequence<sizeof...(args) - 1>{});
}
现在write_indirect
只是将参数包作为元组,并将参数的索引作为模板参数。然后,它使用get
提取最后一个参数,并将其作为第一个参数传递给write_impl
。剩下的参数从元组中解包,并作为第二个参数传递
template<typename... Ts, size_t... Is>
void write_indirect(std::tuple<Ts...> args, std::index_sequence<Is...>)
{
auto constexpr Last = sizeof...(Ts) - 1;
write_impl(std::get<Last>(args), std::get<Is>(args)...);
}
现在write_impl
只是您最初的write
函数,但它将分隔符作为第一个参数
template <typename... Ts>
void write_impl(std::string delimiter, Ts && ...args)
{
((std::cout << args << delimiter),...);
}
这是的演示