c++之可变参数格式化字符串(c++11可变模板参数)

本文将使用 泛型 实现可变参数。 涉及到的关见函数:std::snprintf

1、一个例子

函数声明及定义

1 // 泛型
 2 template <typename... Args> 
 3 std::string show_str(const char *pformat, Args... args)
 4 {
 5     // 计算字符串长度
 6     int len_str = std::snprintf(nullptr, 0, pformat, args...);
 7 
 8     if (0 >= len_str)
 9         return std::string("");
10 
11     len_str++;
12     char *pstr_out    = nullptr;
13     pstr_out        = new(std::nothrow) char[len_str];
14     // 申请失败
15     if (NULL        == pstr_out || nullptr == pstr_out)
16         return std::string("");
17 
18     // 构造字符串
19     std::snprintf(pstr_out, len_str, pformat, args...);
20 
21     // 保存构造结果
22     std::string str(pstr_out);
23 
24     // 释放空间
25     delete pstr_out;
26     pstr_out = nullptr;
27 
28     return str;
29 }

2、一个调用例子

1 std::cout << "str = " << show_str("1-%s, 2-%.2f, 3-%d", "ABC", 12.3456, 100).c_str() << "n";

3、输出结果

演示环境为: VS2015 up3

c++之可变参数格式化字符串(c++11可变模板参数)

4、完整代码

1 #include <iostream>
 2 
 3 // 泛型
 4 template <typename... Args> 
 5 std::string show_str(const char *pformat, Args... args)
 6 {
 7     // 计算字符串长度
 8     int len_str = std::snprintf(nullptr, 0, pformat, args...);
 9 
10     if (0 >= len_str)
11         return std::string("");
12 
13     len_str++;
14     char *pstr_out    = nullptr;
15     pstr_out        = new(std::nothrow) char[len_str];
16     // 申请失败
17     if (NULL        == pstr_out || nullptr == pstr_out)
18         return std::string("");
19 
20     // 构造字符串
21     std::snprintf(pstr_out, len_str, pformat, args...);
22 
23     // 保存构造结果
24     std::string str(pstr_out);
25 
26     // 释放空间
27     delete pstr_out;
28     pstr_out = nullptr;
29 
30     return str;
31 }
32 
33 // 入口函数
34 int main(int argc, char *argv[])
35 {
36     std::cout << "str = " << show_str("1-%s, 2-%.2f, 3-%d", "ABC", 12.3456, 100).c_str() << "n";
37 
38     system("pause");
39     return 0;
40 }

5、总结

A、 new 和 delete 需要配对使用

B、可自定义日志输出格式 和 构造c++格式化字符串。 更加方便输出日志.

6、扩展 (c++11)

A、可变参数模板函数

C++11的新特性--可变模版参数是C++11新增的特性之一,它对参数进行了高度泛化,能表示0到任意个数

一个例子,其定义如下

1 // 可变参数模板函数
2 template <typename ... Args>
3 void vp_func(Args ... args)
4 {
5     // 计算参数个数
6     int count_param = sizeof...(args);
7     std::cout << "参数个数=" << count_param << std::endl;
8 }

其中,计算参数个数的方式:

int count_param = sizeof...(args);

B、调用

1 // 入口函数
 2 int main(int argc, char *argv[])
 3 {
 4     vp_func(1);
 5     vp_func("-=+", 1.23456f);
 6     vp_func(1, 2.2f, "ABC");
 7 
 8     system("pause");
 9     return 0;
10 }

C、输出结果:

演示环境: VS2015 up3

c++之可变参数格式化字符串(c++11可变模板参数)

D、解包(包展开)

有两种方式

1)、递归

2)、非递归

递归,好用,但是要考虑爆栈的情况,不推荐。这里就不介绍了。

下面介绍非递归的方式展开

2.1)、定义展开函数

1 // 参数包展开
2 template<typename T>
3 void expand(const T t)
4 {
5     std::cout << t << std::endl;
6 }

再调用展开函数

1 // 可变参数模板函数
 2 template <typename ... Args>
 3 void vp_func(Args ... args)
 4 {
 5     // 计算参数个数
 6     // int count_param = sizeof...(args);
 7     // std::cout << "参数个数=" << count_param << std::endl;
 8 
 9     std::initializer_list<int>{(expand(args), 0)...};
10     // std::initializer_list<int>{([&] {std::cout << args << std::endl; }(), 0)...};
11 }

2.2)、使用lambda 展开

1 // 可变参数模板函数
 2 template <typename ... Args>
 3 void vp_func(Args ... args)
 4 {
 5     // 计算参数个数
 6     // int count_param = sizeof...(args);
 7     // std::cout << "参数个数=" << count_param << std::endl;
 8 
 9     // std::initializer_list<int>{(expand(args), 0)...};
10     std::initializer_list<int>{([&] {std::cout << args << std::endl; }(), 0)...};
11 }

非lambda完整展开代码:

1 // 参数包展开
 2 template<typename T>
 3 void expand(const T t)
 4 {
 5     std::cout << t << std::endl;
 6 }
 7 
 8 
 9 // 可变参数模板函数
10 template <typename ... Args>
11 void vp_func(Args ... args)
12 {
13     // 计算参数个数
14     // int count_param = sizeof...(args);
15     // std::cout << "参数个数=" << count_param << std::endl;
16 
17     std::initializer_list<int>{(expand(args), 0)...};
18     // std::initializer_list<int>{([&] {std::cout << args << std::endl; }(), 0)...};
19 }

原文链接: https://www.cnblogs.com/pandamohist/p/13629777.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/202407

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月12日 下午9:09
下一篇 2023年2月12日 下午9:09

相关推荐