一:声明
-
auto:
auto
是 C++11 引入的一个关键字,用于自动推断变量的类型。通过使用 auto
,编译器可以根据变量的初始化表达式推断其类型,从而减少代码中的重复冗长的类型声明。
简化模板声明:
for(auto p = vec.begin();p!=vec.end();p++)
-
decltype
decltype
是 C++11 引入的一个关键字,用于获取表达式的类型,而不进行实际的表达式求值。它的作用是让编译器在编译时推断表达式的类型,并将其作为编译器生成的类型声明的一部分。
获取变量的类型:
int x = 5;
decltype(x) y; // y 的类型为 int,与 x 的类型相同
获取表达式的类型:
int a = 10;
double b = 20.5;
decltype(a + b) c; // c 的类型为 double,因为 a + b 的类型为 double
结合 auto
和 decltype
:
int x = 5;
auto y = x; // y 的类型为 int,auto 推断为 int
decltype(auto) z = x; // z 的类型为 int&,decltype(auto) 保留了 x 的引用类型
获取函数返回值类型:
int foo();
decltype(foo()) result; // result 的类型为 foo() 函数返回值的类型
-
auto
:- 简化模板代码,减少模板参数的复杂性。
- 适用于需要简化类型声明,提高代码可读性的场合。
-
decltype
:- 在需要编写泛型代码时,用于捕获表达式的确切类型。
- 与模板结合,用于处理复杂的类型推导,例如迭代器或容器中的类型。
- 在需要保留变量引用类型的场合。
int arr[5] = {1, 2, 3, 4, 5};
decltype(arr) arr_copy; // arr_copy 的类型是 int[5]
auto arr_ref = arr; // arr_ref 的类型是 int*
当我们声明 int arr[5] = {1, 2, 3, 4, 5};
时,我们创建了一个名为 arr
的数组,其中包含了5个整数元素。
-
这行代码中,decltype(arr) arr_copy
:decltype(arr)
将返回arr
的类型,即int[5]
,表示一个包含5个整数元素的数组。因此,arr_copy
的类型也是int[5]
,它是一个未初始化的包含5个整数元素的数组。 -
这里使用auto arr_ref = arr
:auto
推导arr_ref
的类型。因为arr
是一个数组,当数组名被用作表达式时,它会自动退化为指向数组首元素的指针(即int*
类型)。因此,arr_ref
的类型被推导为int*
,表示一个指向整数的指针,指向数组arr
的首元素。
所以,arr_copy
是一个未初始化的包含5个整数元素的数组,而 arr_ref
是一个指向数组 arr
的首元素的指针。
-
返回类型后置
在C++11之前,返回类型通常在函数签名的前面指定,例如:
int add(int a, int b) {
return a + b;
}
然而,随着C++11的引入,一种新的语法允许在函数签名之后指定返回类型,这被称为返回类型后置(Trailing Return Type)。这种语法对于需要从参数中推导返回类型的情况特别有用,并且在与 decltype
结合时非常方便。
#include <iostream>
// 使用返回类型后置来定义一个函数,返回两个输入参数的和。
auto add(int a, int b) -> int {
return a + b;
}
// 使用返回类型后置和 decltype 来推导返回类型。
template <typename T, typename U>
auto multiply(T a, U b) -> decltype(a * b) {
return a * b;
}
int main() {
std::cout << "Add: " << add(3, 4) << std::endl; // 返回类型是 int
std::cout << "Multiply: " << multiply(3, 4.5) << std::endl; // 返回类型由 decltype 推导
return 0;
}
-
模板别名:using=
在C++11中,引入了 using
关键字用于定义模板别名。using
关键字提供了一种更简洁、易读的方式来定义类型别名,特别是在使用模板时。
using alias_name = type;
alias_name
是你为类型定义的别名,而 type
是你要为其创建别名的类型。using
语句可以用于定义任何类型的别名,包括模板类型。
typedef
可以创建基本类型、指针类型、复合类型和函数指针类型的别名。
using
在 C++11 引入之后,成为了更通用的替代方案,可以用于创建类型别名、模板别名以及模板别名模板。
差别在于,新语法可用于模板部分具体化,但typedef不能
template<typename T>
using arr12 = std::arry<T,12>
对于如下声明:
std::array<double,12> a1;
std::array<std::string,12> a2;
可以使用上述具体化模板声明:
arr12<double> a1;
arr12(std::string) a2;
-
nullptr
nullptr
是 C++11 中引入的空指针常量,用于代表空指针。它是一个特殊的字面值,可以被赋值给指针类型,而且不会与整数进行混淆。nullptr
用于替代传统的 NULL
宏,NULL
通常被定义为 0
或者 (void*)0
。因为 NULL
的定义可能是 0
或者指针类型的零值,所以在某些情况下,使用 NULL
可能会引起歧义,特别是在函数重载时。
nullptr
的引入解决了这个问题,它是一个明确的指针值,可以用于初始化任何指针类型,而不会与整数进行混淆。
二:智能指针
智能指针是 C++ 中用于管理动态内存的一种工具,它们可以自动管理内存的