Par*_*duz 5 c++ variadic-functions variadic-templates c++11
我试图在这个问题中使用DanielKO的答案来满足我的需求,但我不熟悉模板和可变函数,我不知道该怎么办.
我需要的是一个可变的c ++(11)函数,我可以像这样调用:
String NewMsg = CreateMessage("SET",16,1,17,0,"RED",47);
Run Code Online (Sandbox Code Playgroud)
并且NewMsg ="SET,0010,0001,0011,0000,RED,002F".
我甚至无法到达应该在参数之间添加逗号的位置.然后:在解析args时如何区分整数和字符串,以便将每个整数格式化为十六进制字符串?
您使用递归和函数重载
std::string CreateMessage(int i)
{
return /* i formatted as hex */;
}
std::string CreateMessage(const char* s)
{
return s;
}
template<typename T, typename... Ts>
std::string CreateMessage(T t, Ts... ts)
{
return CreateMessage(t) + "," + CreateMessage(ts...);
}
Run Code Online (Sandbox Code Playgroud)
混合其他两种解决方案(来自 Passer By 的递归解决方案和来自 Nick Mertin 的 C++17 折叠表达式),您CreateMessage()也可以在 C++11 中无需递归(以类似折叠表达式的方式)编写
std::string const & getStr (std::string const & ret)
{ return ret; }
std::string getStr (int val)
{
std::ostringstream ret;
ret << std::hex << std::setw(4) << std::setfill('0') << val;
return ret.str();
}
template <typename ... Ts>
std::string CreateMessage (Ts const & ... args)
{
using unused = int[];
std::string ret = "";
std::string comma = "";
(void)unused { 0, ( ret += comma + getStr(args), comma = ",", 0 )... };
return ret;
}
Run Code Online (Sandbox Code Playgroud)
- 编辑 -
OP 询问
你想教我“相似折叠”线是如何工作的吗?我该如何“读”它?
嗯...该行如下
(void)unused { 0, ( ret += comma + getStr(args), comma = ",", 0 )... };
Run Code Online (Sandbox Code Playgroud)
其中unused是 的别名 ( using) int[]。
它利用了可变参数包(模板或函数参数)可以在 C 风格数组初始化的上下文中进行扩展的事实,并且还使用了逗号运算符的强大功能(exec/compute 的逗号运算符的专有性并丢弃了在逗号的左边)。
args...所以你有(对于 中的每个参数)的扩展
( ret += comma + getStr(args), comma = ",", 0 )
Run Code Online (Sandbox Code Playgroud)
在哪里
1) 添加comma + getStr(args)到ret, 其中第一个参数为空,以下参数comma等于(参见 (2))","
2)第一个逗号运算符丢弃值ret并分配","给(所以你在第一个和后面comma有一个空commaret +=","ret +=
3)第二个逗号运算符丢弃逗号的值并返回0到初始化unuses
Soret递增,所有getStr(args)数组均由分隔",",未使用的数组用零初始化。
观察另外几点:
a) 在数组(未命名unused)初始化列表中,有一个起始且与可变参数无关的零 ( { 0,);这是必要的,以防args...列表为空,因此该行变为(void)unsed { 0 };,这是合法的,而不是(void)unused { };(没有那个零)这是语法错误
b)unused前面是(void); 这并不是绝对必要的,但对于避免“对象已定义但未使用”类型的警告很有用。
| 归档时间: |
|
| 查看次数: |
167 次 |
| 最近记录: |