我有以下代码将传递给函数的所有参数转换为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中。我无法在呼叫者位置对其进行修改。如何在参数包中处理它?</ p>
答案 0 :(得分:3)
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...);
}
答案 1 :(得分:1)
您只需定义一个重载函数(在下面的示例中为details::print()
)来处理单个数据,然后使用fold expression将它们联接:
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,
您可以通过Jarod的回答方法来消除尾随逗号(尽管您的原始帖子没有抑制它)。
答案 2 :(得分:0)
由于使用递归处理参数包,因此可以添加两个重载
Dafny 2.1.1.10209
stdin.dfy(24,12): Error: member left does not exist in trait Atom
1 resolution/type errors detected in stdin.dfy
并将原始可变参数函数定义更改为
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
。
答案 3 :(得分:0)
我会将迭代与实际操作分开:
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), ...);
}