C++11、C++14、C++17、C++20区别、string、char*、char[]区别

C++11、C++14、C++17、C++20区别

C++11

c++11有如下的语言特性

  • 移动语义
  • auto类型推导
  • 右值引用
  • lambda表达式
  • initializer_list初始化列表
  • decltype类型推导
  • 使用using的类型别名:using vec = std::vector<T>
  • nullptr
  • constexpr常量表达式,使用constexpr表明编译器在编译时期进行计算的表达式
  • final关键字,使得类不能被继承,函数不能被重写
  • delete关键字,使得类中的函数不能被使用
  • 转换构造函数,带有一个参数的构造函数

C++14

  • 二进制字面常量:0b110 = 60b1111'1111 = 255

  • 允许auto关键字可以放置在形参列表上,能够实现lambda表达式的多态

    • auto identity = [](auto x){ return x; };
      int three = identity(3);
      std::string foo = identity("foo");
      
  • 返回值类型推导,auto可以放置在函数的返回类型上,编译器将会自动推断出返回的类型

    • auto f(int i)
      {
          return i;
      }
      
      template<typename T>
      auto& f(T& t)
      {
          return t;
      }
      auto g = [](auto& x)->auto& { return f(x); };
      int y = 123;
      int& z = g(y);		//对y的引用
      
  • decltype(auto):使用decltype(auto)进行类型推断,会保持引用特性;

    • const int x = 0;
      auto x1 = x;			//int
      decltype(auto) x2 = x;	//const int
      int y = 0;
      int& y1 = y;
      auto y2 = y1;			//int
      decltype(auto) y3 = y1; // int&
      int&& z = 0;
      auto z1 = std::move(z); // int
      decltype(auto) z2 = std::move(z); // int&&
      
  • 放松了constexpr函数的限制:在C++11中,constexpr函数体中只可以包含有限的语法,仅仅包含一个return语句。在C++14中,constexpr函数可以包含多种语法,例如if语句,循环等等。

    • constexpr int factorial(int n) {
        if (n <= 1) {
          return 1;
        } else {
          return n * factorial(n - 1);
        }
      }
      factorial(5); // == 120
      
  • 变量模板

    • template<class T>
      constexpr T pi = T(3.1415926535897932385);
      template<class T>
      constexpr T e  = T(2.7182818284590452353);
      

C++17

  • 类模板支持模板参数推导

    • template <typename T = float>
      struct MyContainer {
        T val;
        MyContainer() : val{} {}
        MyContainer(T val) : val{val} {}
        // ...
      };
      MyContainer c1 {1}; // OK MyContainer<int>
      MyContainer c2; // OK MyContainer<float>
      
  • constexpr lambda:编译时期的lambda表达式

    • auto identity = [](int n) constexpr { return n; };
      static_assert(identity(123) == 123);
      
  • 使用auto声明一个无类型的模板参数

    • template <auto... seq>
      struct my_integer_sequence {
        // Implementation here ...
      };
      
      // Explicitly pass type `int` as template argument.
      auto seq = std::integer_sequence<int, 0, 1, 2>();
      // Type is deduced to be `int`.
      auto seq2 = my_integer_sequence<0, 1, 2>();
      
  • 内联变量:inline可以应用在变量

  • 嵌套的命名空间

    • namespace A {
        namespace B {
          namespace C {
            int i;
          }
        }
      }
      
      namespace A::B::C {
        int i;
      }
      
  • 支持UTF-8字面值

  • 支持折叠表达式:在模板参数包中支持折叠表达式,使用运算符作用在包中的每个元素。

    • template <typename... Args>
      bool logicalAnd(Args... args) {
          // Binary folding.
          return (true && ... && args);
      }
      bool b = true;
      bool& b2 = b;
      logicalAnd(b, b2, true); // == true
      
      template <typename... Args>
      auto sum(Args... args) {
          // Unary folding.
          return (... + args);
      }
      sum(1.0, 2.0f, 3); // == 6.0
      
  • lambda表达式可以按值捕获this指针

    • struct MyObj {
        int value {123};
        auto getValueCopy() {
          return [*this] { return value; };
        }
        auto getValueRef() {
          return [this] { return value; };
        }
      };
      MyObj mo;
      auto valueCopy = mo.getValueCopy();
      auto valueRef = mo.getValueRef();
      mo.value = 321;
      valueCopy(); // 123
      valueRef(); // 321
      

C++20

  • 支持协程

  • 支持concepts概念

  • 指定的初始化器语法:任何没有列出名字的变量都被指定为默认初始化方式

    • struct A {
        int x;
        int y;
        int z = 123;
      };
      
      A a {.x = 1, .z = 2}; // a.x == 1, a.y == 0, a.z == 2
      
  • 模板可以应用在lambda表达式中

    • auto f = []<typename T>(std::vector<T> v) {
        // ...
      };
      
  • lambda表达式可以捕获参数包

    • template <typename... Args>
      auto f(Args&&... args){
          // BY VALUE:
          return [...args = std::forward<Args>(args)] {
              // ...
          };
      }
      
      template <typename... Args>
      auto f(Args&&... args){
          // BY REFERENCE:
          return [&...args = std::forward<Args>(args)] {
              // ...
          };
      }
      
  • immdiate functions:类似constexpr函数,但是使用consteval关键字声明,该函数必须产生一个常量值。

    • consteval int sqr(int n) {
        return n * n;
      }
      
      constexpr int r = sqr(100); // OK
      int x = 100;
      int r2 = sqr(x); // ERROR: the value of 'x' is not usable in a constant expression
                       // OK if `sqr` were a `constexpr` function
      
  • constexpr虚函数:在C++20中,虚函数支持constexpr

    • struct X1 {
        virtual int f() const = 0;
      };
      
      struct X2: public X1 {
        constexpr virtual int f() const { return 2; }
      };
      
      struct X3: public X2 {
        virtual int f() const { return 3; }
      };
      
      struct X4: public X3 {
        constexpr virtual int f() const { return 4; }
      };
      
      constexpr X4 x4;
      x4.f(); // == 4
      

string、char*、char[]

char*

char* str = "this is GeeksForGeeks";

优点:

  • 只需要一个指针即可指向整个字符串,高效利用内存;
  • 不需要事先声明字符串的大小;

缺点:

  • 不可以修改字符串,可以更改指针的指向,但是不能够更改指针所指的字符串;

    • char* str = "hello";
      str[1] = 'o';	//错误的
      
  • 使用这种方法在C语言中是可以的,但是在C++中不推荐,因为在C语言中,string字面值表示的是一个char类型的数组,但是在C++中,字符串字面值表示的是一个常量的char类型的数组,使用上面的方式,编译器会提示警告,所以在C++中应该使用const char* str = "字符串"

string

对于string来说,其内部处理字符数组的存储,string不用负责内存的分配和释放,而char*需要考虑内存释放和越界问题;除此之外,string内部封装了很多字符串处理的函数,例如查找,替换,搜索,插入等操作函数。

以下几种情况下使用char* 比使用std::string要好

  • 与旧C代码兼容;
  • 节省内存;
  • 在与操作系统等底层系统进行通信时,适合使用char*

char[]

char str[] = "This is GeeksForGeeks";
     or 
char str[size] = "This is GeeksForGeeks";

优点:

  • 可以修改字符串;

    • char str[] = "Hello";
      str[1] = 'o';	//正确
      

缺点:

  • 在堆上分配空间,分配的空间是固定的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值