c++11 new feature

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;
}

智能指针

智能指针














原文地址:https://www.cnblogs.com/rogerroddick/p/2846706.html