std::inistializer_list
使用inistializer_list能够初始化同一类型或者能够隐式转换成统一类型的函数形参,简化函数接口的实行,例如:
double Sum(std::initializer_list<double>li)
{
double sum = 0.0;
for(auto p = li.begin(); p != li.end(); p++)
{
sum += *p;
}
return sum;
}这样调用函数的方式可以是多个参数:
cout<<Sum({1.2})<<endl;
cout<<Sum({1.2, 1.3})<<endl;
cout<<Sum({})<<endl;注意花括号是不能省略的。
如果不使用initializer_list则需要使用varg_list来实现变参函数:
#include <cstdarg>
double Sum(int num, ...)
{
double sum = 0.0;
va_list _v;
va_start(_v, num);
for (int i = 0; i < num; i++)
{
sum+=va_arg(_v, double);
}
va_end(_v);
return sum;
}调用例子为:
cout<<Sum(1, 1.2)<<endl;
cout<<Sum(2, 1.2, 1.3)<<endl;
cout<<Sum(0)<<endl;可以看出来va_list来实现需要提供一个额外的参数来告诉实现函数变参有多少个,假如给出个数的比实际输入的少,截取前面的个数进行处理,给多了按照实际的输入进行处理,不会抛出异常。
对比两个可以看出前者具有强类型校验,能够在编译期发现错误,va_list则不行,同时前者不需要提供变参个数。
这里结合模板来实现一个简单的加法器
template <typename T>
T Sum(std::initializer_list<T> li)
{
T sum{};
for (auto p = li.begin(); p != li.end(); p++)
sum += *p;
return sum;
}调用例子: cout<<Sum<double>({1.2, 1.3})<<endl;
cout<<Sum<double>({})<<endl;
如果编译器不支持auto关键字,请使用 std::initializer_list<double>::iterator.
decltype 与返回类型后置
没有decltype之前如果需要实现下例Sum加法器是十分困难的。
template <typename T1, typename T2>
T1 Sum(T1 t1, T2 t2)
{
return t1 + t2;
}
cout<<Sum<int, double>(1, 1.2)<<endl;
cout<<Sum<double, int>(1.2, 1)<<endl;输出结果不一样,前者是整数2,后者是2.2。
使用新语法将函数的返回类型放置到参数列表后面:
template <typename T1, typename T2>
auto Sum(T1 t1, T2 t2) -> decltype(t1 + t2)
{
return t1 + t2;
}
智能指针
智能指针
浙公网安备 33010602011771号