У меня ниже код для преобразования всех аргументов, переданных функции, в csv:
void Parse(ostream& os)
{
}
template <typename T, typename... Args>
void Parse(ostream& os, T t, Args... args)
{
os << *t << ',';
Parse(os, args...);
}
Хотя это отлично работает для всех типов данных, что я делаю, мне нужна особая обработка для типов данных char. Если есть параметр char (например, 0), я хочу преобразовать его в ascii (48 для нуля), а затем добавить его в csv. Я не могу изменить его у вызывающего абонента. Как я могу справиться с этим в пакете параметров?





template <typename T, typename... Args>
void Parse(ostream& os, T t, Args... args)
{
if constexpr(std::is_same_v<T, char>)
{
os << to_ascii(t) << ',';
}
else
{
os << *t << ',';
}
Parse(os, args...);
}
Поскольку вы используете рекурсию для обработки пакета параметров, вы можете добавить две перегрузки
void Parse(ostream& os) {} /* As before. */
void Parse(ostream& os, char *c)
{
os << handleChar(*c) << ",";
}
template <class T> void Parse(ostream& os, T t)
{
os << *t << ",";
}
и измените определение исходной вариативной функции на
template <typename T, typename... Args>
void Parse(ostream& os, T t, Args... args)
{
Parse(os, t);
Parse(os, args...);
}
Компилятор предпочтет эту функцию без шаблона при вызове Parse с двумя аргументами, вторым из которых является char*.
Вы просто определяете перегруженную функцию (details::print() в примере ниже) для работы с одной датумом, а затем присоединяете их, используя сложить выражение:
namespace details {
template<typename T>
void print(std::ostream&os, T const&x)
{ os << x << ','; } // print any value
template<typename T>
void print(std::ostream&os, T*x)
{ print(os,*x); } // print value pointed to
template<typename T>
void print(std::ostream&os, const T*x)
{ print(os,*x); } // print value pointed to
void print(std::ostream&os, const char*x)
{ os << x << ','; } // print C-style string
}
template<typename...Args>
void parse(std::ostream&os, const Args& ...args)
{
(details::print(os,args) , ...); // fold expression
}
int main()
{
double x=3.1415;
parse(std::cout,"fun",42,'d',&x);
}
вывод: fun,42,d,3.1415,
Вы можете подавить конечную запятую методом ответа Джарода (хотя ваш исходный пост не подавлял это).
Я бы отделил итерацию от реального действия:
template <typename T>
void Handle(std::ostream& os, const char*& sep, T arg)
{
os << sep << arg;
sep = ",";
}
void Handle(std::ostream& os, const char*& sep, char arg)
{
os << sep << (int)arg;
sep = ",";
}
template <typename... Args>
void Parse(std::ostream& os, Args... args)
{
const char* sep = "";
(Handle(os, sep, args), ...);
}