C++11 您所在的位置:网站首页 下面520上面1314符号 C++11

C++11

2024-01-14 02:31| 来源: 网络整理| 查看: 265

转载来自:https://subingwen.cn/cpp/autotype/

在 C++11 中增加了很多新的特性,比如可以使用 auto 自动推导变量的类型,还能够结合 decltype 来表示函数的返回值。使用新的特性可以让我们写出更加简洁,更加现代的代码。

1. auto在 C++11 之前 auto 和 static 是对应的,表示变量是自动存储的,但是非 static 的局部变量默认都是自动存储的,因此这个关键字变得非常鸡肋,在 C++11 中他们赋予了新的含义,使用这个关键字能够像别的语言一样自动推导出变量的实际类型。

1.1 推导规则C++11 中 auto 并不代表一种实际的数据类型,只是一个类型声明的 “占位符”,auto 并不是万能的在任意场景下都能够推导出变量的实际类型,使用auto声明的变量必须要进行初始化,以让编译器推导出它的实际类型,在编译时将auto占位符替换为真正的类型。使用语法如下:

auto 变量名 = 变量值; auto x = 3.14; // x 是浮点型 double auto y = 520; // y 是整形 int auto z = 'a'; // z 是字符型 char auto nb; // error,变量必须要初始化 auto double nbl; // 语法错误, 不能修改数据类型

 

不仅如此,auto 还可以和指针、引用结合起来使用也可以带上 const、volatile 限定符,在不同的场景下有对应的推导规则,规则内容如下:

当变量不是指针或者引用类型时,推导的结果中不会保留 const、volatile 关键字当变量是指针或者引用类型时,推导的结果中会保留 const、volatile 关键字

int temp = 110; auto *a = &temp; auto b = &temp; auto &c = temp; auto d = temp;

 

 

 这边可以看到

a 是 int*

b 是int*

c 是int&

d 是int

 

int tmp = 250; const auto a1 = tmp; auto a2 = a1; const auto& a3 = tmp; auto& a4 = a3;

 

 

 可以看到

a1 是 const int

a2却看到const没有了

a3是const int&

a4是const int&

1.2 auto的限制

auto 关键字并不是万能的,在以下这些场景中是不能完成类型推导的:

不能作为函数参数使用。因为只有在函数调用的时候才会给函数参数传递实参,auto 要求必须要给修饰的变量赋值,因此二者矛盾。

int func(auto a, auto b) // error { cout double decltype(a+b*c) d = 520.1314; // d -> double

 

可以看到 decltype 推导的表达式可简单可复杂,在这一点上 auto 是做不到的,auto 只能推导已初始化的变量类型。

2.1 推导规则通过上面的例子我们初步感受了一下 decltype 的用法,但不要认为 decltype 就这么简单,在它简单的背后隐藏着很多的细节,下面分三个场景依次讨论一下:

表达式为普通变量或者普通表达式或者类表达式,在这种情况下,使用 decltype 推导出的类型和表达式的类型是一致的。

#include #include using namespace std; class Test { public: string text; static const int value = 110; }; int main() { int x = 99; const int& y = x; decltype(x) a = x; decltype(y) b = x; decltype(Test::value) c = 0; Test t; decltype(t.text) d = "hello, world"; return 0; }

变量 a 被推导为 int 类型变量 b 被推导为 const int & 类型变量 c 被推导为 const int 类型变量 d 被推导为 string 类型表达式是函数调用,使用 decltype 推导出的类型和函数返回值一致。

 

#include #include using namespace std; class Test { public: string text; static const int value = 110; }; //函数声明 int func_int(); // 返回值为 int int& func_int_r(); // 返回值为 int& int&& func_int_rr(); // 返回值为 int&& const int func_cint(); // 返回值为 const int const int& func_cint_r(); // 返回值为 const int& const int&& func_cint_rr(); // 返回值为 const int&& const Test func_ctest(); // 返回值为 const Test int main() { //decltype类型推导 int n = 100; decltype(func_int()) a = 0; decltype(func_int_r()) b = n; decltype(func_int_rr()) c = 0; decltype(func_cint()) d = 0; decltype(func_cint_r()) e = n; decltype(func_cint_rr()) f = 0; decltype(func_ctest()) g = Test(); return 0; }

 

 变量 a 被推导为 int 类型

变量 b 被推导为 int& 类型变量 c 被推导为 int&& 类型变量 d 被推导为 int 类型变量 e 被推导为 const int & 类型变量 f 被推导为 const int && 类型变量 g 被推导为 const Test 类型

函数 func_cint () 返回的是一个纯右值(在表达式执行结束后不再存在的数据,也就是临时性的数据),

对于纯右值而言,只有类类型可以携带const、volatile限定符,除此之外需要忽略掉这两个限定符,因此推导出的变量 d 的类型为 int 而不是 const int。

表达式是一个左值,或者被括号 ( ) 包围,使用 decltype 推导出的是表达式类型的引用(如果有 const、volatile 限定符不能忽略)。

#include #include using namespace std; class Test { public: int num; }; int main() { const Test obj; //带有括号的表达式 decltype(obj.num) a = 0; decltype((obj.num)) b = a; //加法表达式 int n = 0, m = 0; decltype(n + m) c = 0; decltype(n = n + m) d = n; return 0; }

obj.num 为类的成员访问表达式,符合场景 1,因此 a 的类型为 intobj.num 带有括号,符合场景 3,因此 b 的类型为 const int&。n+m 得到一个右值,符合场景 1,因此 c 的类型为 intn=n+m 得到一个左值 n,符合场景 3,因此 d 的类型为 int&

2.2 decltype 的应用关于 decltype 的应用多出现在泛型编程中。比如我们编写一个类模板,在里边添加遍历容器的函数,操作如下:

#include using namespace std; template class Container { public: void func(T& c) { for (m_it = c.begin(); m_it != c.end(); ++m_it) { cout


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有