前言:
而今咱们对“c语言datatype”大约比较着重,姐妹们都需要剖析一些“c语言datatype”的相关知识。那么小编同时在网上汇集了一些关于“c语言datatype””的相关知识,希望小伙伴们能喜欢,我们一起来了解一下吧!C++11引入的类型推导功能是从许多程序员一直想要的简化样板代码的方法。C++11的类型推导功能为程序员提供了更易读、更简洁的代码。
本文将介绍三种类型推导功能: auto, decltype,它们分别提供了不同使用场景下的类型推导方案。
auto关键字
auto关键字最基本的使用方式
C++引入auto关键字主要有两种用途:
一是在变量声明时根据初始化表达式自动推断该变量的类型。
二是在声明函数时作为函数返回值的占位符。
auto a = 1;//10是int型,可以自动推导出a是intint i = 1;auto b = i ; //b是int型auto c = 2.0 //d是double型
上述就是auto的基本使用方法,通过=右边的类型推导出变量的类型。
auto关键字的推导规则
auto关键字的推导规则可能会产生普遍复杂的问题。在这里,我们将详细讨论auto关键字如何推导类型,它的重载规则以及如何解决潜在的类型问题。
auto的推导的使用规则和限制:
使用auto关键字的变量必须有初始值。auto在一行定义多个变量时,各个变量的推导不能产生二义性,否则编译失败auto不能用作函数参数可以使用valatile,*(指针类型说明符),&(引用类型说明符),&&(右值引用)来修饰auto关键字。在类中auto不能用作非静态成员变量auto不能定义数组,可以定义指针auto无法推导出模板参数使用auto关键字声明变量的类型,不能自动推导出顶层的CV-qualifiers和引用类型,除非显示声明。
我们将通过一些常见的扩展示例来讲解auto关键字的推导规则。
示例1
int i=100; auto a = i, &b = i, *c = &i; // a 是int型,b是i的引用, C是i的指针, auto其实相当于intauto d = 0, f = 1.0; // 0 和1.0类型不同, 对于编译器有二义性,没有办法推导,汇报如下的错误 // error: inconsistent deduction for 'auto': 'int' and then 'double'auto e; //错误,使用auto之后需要立即初始化,否则无法推导类型。报错信息如下 //error: declaration of 'auto e' has no initializer
示例2
void func(auto param){} //auto不能用作函数参数 //error: 'auto' parameter not permitted in this context.class ClassA{ auto a = 1; //error: non-static data member declared with placeholder 'auto' //auto不能用于非静态成员变量 //如下两个也是错误的,与auto无关。ISO C++禁止在类中初始化非常量静态成员 static auto b = 1; //error: ISO C++ forbids in-class initialization of non-const static member 'ClassA::b' static int c = 1; //error: ISO C++ forbids in-class initialization of non-const static member 'ClassA::c' static const auto d = 1; //这么定义没问题}void funciton(){ int a[10] = {0}; auto b = a; auto c[10] = a; //auto不能定义数组,可以定义指针 //error: 'c' declared as array of 'auto' vector<int> d; vector<auto> f = d; //auto无法推导出模板参数 error: invalid use of 'auto' //error: cannot convert 'std::vector<int>' to 'int' in initialization}
示例3:使用指针修饰auto关键字
auto a = 10; auto *pa = new auto(a); auto **ppa = new auto(&a); cout << "a type:" <<typeid(a).name() << endl; // 输出: int 或 i cout << "pa type:" typeid(pa).name() << endl; // 输出: int * 或 pi cout << "ppa type:" typeid(ppa).name() << endl; // 输出: int ** 或 ppi
示例4:使用CV-qulifiers及引用修饰auto
int i = 100; int &ref = i; auto a = ref; a = 15; //重新赋值 cout << "i = " << i << ", a = " << a << endl; //i = 100, a = 15 //显示声明 auto &b = ref; b = 15; cout << "i = " << i << ", a = " << a << endl; //i = 15, a = 15
示例5:使用const修饰auto
const int a =100; auto b = a; a = 110; //error: assignment of read-only variable 'a' b = 111; //显示声明 const auto c = a; c = 115; //error: assignment of read-only variable 'c'
示例6:数组类型,auto关键字会推导为指针类型,除非被声明为引用
int a[10]; auto b = a; cout << typeid(b).name() << endl; // 输出:int * 或 Pi auto &c = a; cout << typeid(c).name() << endl; // 输出:int [10] 或 A10_iauto关键字的使用警惕
但使用auto从初始化表达式中推断出变量的数据类型,可以大大简化我们的编程工作,特别是对于一些类型冗长复杂的变量。
比如对于vector类型的变量,如果我们需要获取它的迭代器,我们需要这样声明vector::iterator iter,而使用auto关键字后我们可以让编译器帮我们推断出迭代器的具体类型。
在模板函数定义时,如果变量的类型依赖于模板参数,我们也很难确定变量的类型,使用auto关键字则可以把这些“脏活累活”交给编译器完成。
但同时使用auto也会带来潜在的问题,这些问题可能会影响代码的维护和可读性。所以使用的时候要采用更加规范的代码风格来优化程序的开发。
decltype关键字decltype关键字的基本使用
decltype关键字提供了获取表达式的类型的方法,可以用于在特定情况下推导类型。相对于auto关键字而言,decltype关键字更灵活,可以推导输出的类型是从一些源代码基于已知变量的精确的类型中推导出来的。
decltype关键字的日常使用
在这里,我们将讨论如何使用decltype关键字来推断算术表达式的类型,如何使用decltype关键字来推断原型中的参数类型以及如何使用auto和decltype关键字带来的想象力来更好地利用类型推导。
int function() { return 0; }decltype(function()) i; // i为int类型int x = 0;decltype(x) y; // y是int类型decltype(x + y) z; // z是int类型
decltype不会像auto一样忽略引用和cv属性,decltype会保留表达式的引用和cv属性
const int &a= 1;decltype(a) b = 2; // b是const int&
int a = 0, b=1;decltype(a+b) c = 0; // c是int,因为(a+b)返回一个右值decltype(a +=b) d = c; //d是int&,因为(a +=b)返回一个左值decltype关键字使用场景的限制
虽然decltype关键字带来很多优势,但它也有一些使用场景的限制。这种限制是由语言的规则和约定所决定的。我们将讨论这些限制,以便更好地了解何时使用decltype关键字并将其用于我们程序中。
decltype关键字只能推导表达式的类型,不能推导语句的类型。在使用decltype关键字时需要注意语句和表达式的区别。如果一个表达式的类型是一个左值引用,那么decltype关键字将返回被引用对象的类型,而不是引用类型本身的类型。如果一个表达式是一个函数调用,那么decltype关键字将返回函数的返回值类型,而不是函数类型本身。在使用decltype关键字时,被推导表达式必须是完整的表达式,不能是一个未求值的表达式。结论
总结重要点,介绍更多关于类型推导的实践,包括最近的C++17版本带来的稍微改进的类型推导机制;提供一些工具来帮助程序员更好地使用类型推导,并建议一些打破常规的代码风格。
标签: #c语言datatype