C++ 变长参数、模板递归

一、C 风格变长参数函数
最具代表性:int printf(const char *format, …);
可能的实现:

int printf(const char *fmt, ...)
{
    int _cnt = 0;
	char* _sv = 0;
	double _dv = 0.0;
	int _iv = 0;

	va_list _args;
	va_start(_args, fmt);

	for (const char* p=fmt; *p; ++p)
	{
	    ++_cnt;
		// 对 *p 进行条件判断
		if (*p != '%')
		{
			// do something
		}
		else
		{
			switch (*(++p))
			{
				case 'd':
					_iv = va_arg(_args, int);
					// do something
					break;

				case 'f': 
					_dv = va_arg(_args, double);
					// do something
					break;

				case 's':
					for (_sv=va_arg(_args, char*); *_sv; ++_sv)
					{
						// do something
					}

					break;

				default:
					// do something
					break;
			}
		}
	}

	va_end(_args);
	return _cnt;
}

内部主要是利用 va_list、va_start、va_arg、va_end 这 4 个宏将参数展开,并根据 fmt 指定的内容进行格式化。

二、C++ 风格模板递归(c++11 标准支持)

template <typename T>
void FormatHelper(std::stringstream& ss, const T& t)
{
	ss << t;
}

template <typename T1, typename ...Tn>
void FormatHelper(std::stringstream& ss, const T1& t1, const Tn& ...tn)
{
	ss << t1;
	FormatHelper(ss, tn...);
}

template <typename ...Args>
std::string Format(const Args& ...args)
{
	std::stringstream ss;
	ss.setf(std::ios::fixed); // 格式化浮点数时可能需要此行
	FormatHelper(ss, args...);
	return ss.str();
}

主要是利用C++的多态和模板泛型编程,自动构建各匹配函数,将参数展开。

三、C++ 折叠表达式(C++17 标准支持)

template <typename ...Args>
std::string Format(const Args& ...args)
{
	std::stringstream ss;
	ss.setf(std::ios::fixed); // 格式化浮点数时可能需要此行
	(ss << ... << args); // 折叠表达式精髓
	return ss.str();
}

更简洁的代码。

四、调用示例

C:
	printf("format to a string: %d, %.5f, %s\n", 100, 12345.123456789, "abcd");
	
C++:
	std::cout << Format("format to a string: ", 100, ", ", std::setprecision(5), 12345.123456789, ", ", "abcd") << std::endl;

输出:
	format to a string: 100, 12345.12346, abcd
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值