参数包后的字符串参数

问题描述

我想编写一个函数 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,","); // comma as delimeter 

现在,自动类型推导失败,因为 C++ 期望参数包是最后一个参数。

我怎样才能做到这一点?

解决方法

您可以使用此 blog article 中的一个很好的技巧。

修改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),...);
}

这是一个demo