C++11 的新特性

C++ 11 新特性

1.nullptr

2.auto、decltype

C++11:

template<typename T, typename U>
auto add(T x, U y) -> decltype(x+y) {
    return x+y;
}

C++14:

template<typename T, typename U>
auto add(T x, U y) {
    return x+y;
}

3.区间迭代

std::vector<int> arr(5, 100);
for(std::vector<int>::iterator i = arr.begin(); i != arr.end(); ++i) {
    std::cout << *i << std::endl;
}

c++11:
// & 启用了引用
for(auto &i : arr) {    
    std::cout << i << std::endl;
}

4.初始化列表

struct A {
    int a;
    float b;
};
struct B {    uhh
    B(int _a, float _b): a(_a), b(_b) {}
private:
    int a;
    float b;
};

A a {1, 1.1};    // 统一的初始化语法
B b {2, 2.2};

5.模板增强

外部模板:

C++11 引入了外部模板,扩充了原来制编译器在特定位置实例化模板的语法,使得能够显式的告诉编译器何时进行模板的实例化

template class std::vector<bool>;            // 强行实例化
extern template class std::vector<double>;  // 不在该编译文件中实例化模板

在传统 C++ 的编译器中,>>一律被当做右移运算符来进行处理。但实际上我们很容易就写出了嵌套模板的代码:

std::vector<std::vector<int>> wow;1

这在传统C++编译器下是不能够被编译的,而 C++11 开始,连续的右尖括号将变得合法,并且能够顺利通过编译。

类型别名模板

type可以为应该类型定义一个新名称,但是不能为一个模板定义新的名称

C++11 使用using 可以 定义别名

template< typename T, typename U, int value>
class SuckType {
public:
    T a;
    U b;
    SuckType():a(value),b(value){}
};
template< typename U>
typedef SuckType<std::vector<int>, U, 1> NewType; // 不合法

template <typename T>
using NewType = SuckType<int, T, 1>;    // 合法

默认参数模板

定义一个加法函数

template<typename T, typename U>
auto add(T x, U y) -> decltype(x+y) {
    return x+y
}

每次使用都有指定他的参数类型,C++11可以指定模板的默认参数

template<typename T = int, typename U = int>
auto add(T x, U y) -> decltype(x+y) {
    return x+y;
}

6.构造函数

委托构造:

可以在同一个类中一个构造函数调用另一个构造函数

继承构造:

继承的时候,如果派生类想要使用基类的构造函数需要在构造函数中显示的声明,如果基类有很多种不同版本的构造函数,派生类中就得写很多对应的"透传"构造函数

struct A
{
  A(int i) {}
  A(double d,int i){}
  A(float f,int i,const char* c){}
  //...等等系列的构造函数版本
};
struct B:A
{
  B(int i):A(i){}
  B(double d,int i):A(d,i){}
  B(folat f,int i,const char* c):A(f,i,e){}
  //......等等好多个和基类构造函数对应的构造函数
};
struct A
{
  A(int i) {}
  A(double d,int i){}
  A(float f,int i,const char* c){}
  //...等等系列的构造函数版本
};
struct B:A
{
  using A::A;
  //关于基类各构造函数的继承一句话搞定
  //......
};

如果一个继承构造函数不被相关的代码使用,编译器不会为之产生真正的函数代码,这样比透传基类各种构造函数更加节省目标代码空间。

posted @ 2020-08-05 14:00  buerdepepeqi  阅读(201)  评论(0编辑  收藏  举报