小白入门C++11可变参数模板函数简单例子
c++11可变参数模板函数
虽然在模板方面是小白,也能清晰认识到可变参数模板函数很强大,用好了,对写一些基础框架类很有帮助。但是小
白看c++相关技术文章,最怕的就是遇到模板相关内容,如果用四个字来形容就是晦涩难懂,如果用两个字来形容就
是头大。得益于去年双十一京东做活动,买了基本c++技术书籍,其中有本《深入应用C++11代码优化与工程级应
用》,这本书不入门模板知识点的话,连几页都翻不下去了,只好硬着头皮看书。因为深知光看书不动手练习的话,
好像是理解了,其实coding时,根本不知道敲啥。
一个简单的求和例子
下面用一个简单的求和例子来简单演示下如何使用可变参数模板函数,设计一个函数,输入N(N>0)个数字,int或者float等类型,返回数字的和;输入N(N>0)个字符,string类型,返回字符拼接后的字符串。即输入,1,2.1,3,4,返回值为10.1;输入“1”,“2”,“3”,“4”,返回值为“1234”。直接上代码,开发环境是win10+VS2019:
template<class V>
V add(V v) {
return v;
}
template<class T, typename… Args>
auto add(T t, Args… args) {
return t + add(args…);
}
#include <iostream>
using namespace std;
int main()
{
float ia = add(1,2.1,3.2,4,5);
cout << “ia=” << ia << endl;
string str1 = "1";
string str2 = "2";
string str3 = "3";
string str4 = "4";
string str5 = "5";
std::string sb = add(str1, str2, str3, str4, str5);
cout << "sb=" << sb << endl;
system("PAUSE ");
}
此处分享一个查看模板编译展开代码的网站,我也是在知乎上看到别人提到的,觉得还不错:https://cppinsights.io/,可以看到上面模板函数代码展开的关键代码如下所示:
#ifdef INSIGHTS_USE_TEMPLATE
template<>
double add<double, double, int, int>(double t, double __args1, int __args2, int __args3)
{
return t + add(__args1, __args2, __args3);
}
#endif
这里有一个小地方要注意的是,如果上面的函数返回值不用auto,而用T的话,那么,上述模板函数代码展开的关键代码如下所示:
/* First instantiated from: insights.cpp:16 */
#ifdef INSIGHTS_USE_TEMPLATE
template<>
int add<int, double, double, int, int>(int t, double __args1, double __args2, int __args3, int __args4)
{
return static_cast(static_cast(t) + add(__args1, __args2, __args3, __args4));
}
#endif
这个时候返回值就是int类型,上述例子中的加法运算就会结果精度不对。
除了用auto自动推导返回值外,我在百度搜索相关内容时,还看到有人推荐的其他方法,不过说实话,我这种小白,基本是没看到,希望有看懂的大佬可以指点下。
https://www.imooc.com/wenda/detail/593318
上面链接中的方法如下:
template<typename… T>
struct TypeOfSum;
template<typename T>
struct TypeOfSum<T> {
typedef T type;
};
template<typename T, typename… P>
struct TypeOfSum<T,P…> {
typedef decltype(T() + typename TypeOfSum<P...>::type()) type;
};
template <class T>
T sum(const T& in)
{
return in;
}
template <class T, class… P>
typename TypeOfSum<T,P…>::type sum(const T& t, const P&… p)
{
return t + sum(p…);
}