浅谈C++2.0新特性|8月更文挑战

693 阅读4分钟

1、语法糖auto

以前版本关键字auto是一个存储类型说明符,表示动态存储还是静态存储,与static关键字对应。

C++2.0新标准引入了auto类型说明符,用它就能让编译器替我们去分析表达式所属类型。

简单来说就是auto通过初始值自动推算变量类型,即自动类型推断。

auto使用要注意以下几点:

1、auto定义的变量必须有初始值;

2、auto可以在一条语句中声明多个变量,但该语句所有变量的初始基本数据类型都必须一样,因为一条声明语句只能有一个基本数据类型;

3、auto把引用类型会推断为引用对象,即引用对象的类型作为auto类型;

4、auto一般会忽略掉顶层const,底层const一般会保留,如果希望是(顶层)const ,需要显示声明;

5、auto若果将变量设为引用类型,不能为非常量引用绑定字面值(引用的知识);

6、auto 不能用于函数形参!!!!如void f(auto x);

代码测试如下:

#include "iostream"
#include "string"
double f(int a,int b){return 0;}
auto pf=f;//auto必须有初值
int main(int argc,char const *argv[]){
    auto a=1;
    auto b=1.2;
    auto ptr=&a;
    std::string s="******";
    auto s_begin=s.begin();
    auto c=s;

    int *p=0,x=1;
    auto i=0,*pos=&i;//true:i是整数,p是整形指针;
    //auto iz=0,pi=2.56;//error:iz与pi类型不一致

    int ii=0,&ir=ii;
    auto a=ir;  //a是整数,且等于零

    const int ic=0,&icr=ic;
    auto m=ic;//整数
    auto n=icr;//整数
    auto o=ⅈ//整型指针
    auto p=⁣//指向整型常量的指针

    const auto y=ic;//y是const int

    auto &_r=ic; //指向ic的引用
    //auto &_s=42;//error:不能为非常量引用绑定字面值
    const auto &_s=42;//常量引用

    const int &h=42;
    //int &h=42;//error:不能为非常量引用绑定字面值
    
    return 0;
}

2、语法糖原始字面量(原始字符串)

在编程中假如遇到了字符串“\n”,这里表示换行的意思,即"\n"表示的是一个字符——换行。那如果我们想表示一个'\'为一个'\'该怎么办呢?在C语言中是这样写"\\n"。一个这样写很容易,但一个字符串里有多个\与字母的组合时我们只想让其表达字面意思怎么办呢?这时原始字面量出场了。

定义方式为R “xxx(原始字符串)xxx” ;

注意:即R后面的两处xxx字符要完全一样。否则编译报错。

代码测试如下:

#include<iostream>
#include<string> 
int main(int argc,char const *argv[])
{
    std::string str = "D:\C++\test.cpp";
    std::cout << str << std::endl;
    std::string str = "D:\\C++\\test.cpp";
    std::cout << str1 << sdt::endl;
    sdt::string str = R"(D:\C++\test.cpp)";
    sdt::cout << str2 << sdt::endl;

    return 0;
}

3、基于范围的for循环

C++2.0新标准引入了一种更简单的for语句,这种语句可以遍历容器或其他序列的所有元素;语法形式如下:

for(declaration:expression)statementfor(declaration:expression)\\statement\\

1、expression为序列或容器的实例对象

2、declaration为容器或序列内部的具体类型

3、statement具体要操作的表达式

测试代码如下:

#include <iostream>
#include <vector>
int main()
{
    std::vector<std::pair<int,int>> t(10,std::make_pair(1,2));
    for (auto x:t)
    {
        std::cout << x.first<< "**"<<x.second<<std::endl;
    }
    
    return 0;
}

注意:

1、for (auto x:t),这里是值传递,for (auto &x:t)改成这样是引用传递

2、auto自动类型推导出类型,当然也可以显示声明

3、这里的x为std::pair<int,int>类型;

4、列表初始化

C++2.0扩大了用大括号括起的列表(初始化列表)的适用范围,使用列表初始化时,可添加=,也可以不添加。如下所示:

int x={5};
double y {2.75};
short quar [5] {4,5,2,76,1};

另外,列表初始化语法也可以用于new表达式中:

int *ar = new int [4] {6,6,6,6};

创建对象时,也可以使用大括号(而不是圆括号)括起的列表来调用构造函数:

class test{
    private:
    	int x;
    	int y;
    	int z;
    public:
    	test(int M,int N,int Q):x(M),y(N),z(Q){};
};

test t1{1,2,3};
test t2={2,3,4};//调用的是构造函数

列表初始化的好处:

初始化列表语法可防止缩窄,即禁止将数值赋给无法存储他的数值变量。常规初始化允许程序员执行可能没有意义的操作,例如:

char c1=11111;//警告
char c2={11111};//错误
char c3={100};//允许

将std::initialzer_list作用于常规函数参数:

#include "iostream"
#include "string"
#include "initializer_list"
using namespace std;
void test(initializer_list<int> i){
    int addr=0;
    for(auto pos=i.begin();pos!=i.end();++pos){
        cout<<"pos="<<*pos<<endl;
    }
}
int main(int argc,char const *argv[]){
    test({1,2,3,4,5});
    
    return 0;
}