C语言auto和C++auto用法有什么区别?
C 语言的 auto
关键字表示自动变量,用于将变量声明为存储在栈上的局部变量。在 C++ 中,auto
关键字已经不再是必要的,因为在没有使用其他存储类别关键字(如 static
)时,变量默认是自动存储的。
而在 C++ 中,auto
关键字的含义发生了变化,它现在用于类型推导,可以让编译器根据变量的初始化表达式自动推导出变量的类型。例如:
auto i = 1; // 推导出 i 的类型为 int
auto d = 3.5; // 推导出 d 的类型为 double
在 C++11 标准中,在 C++14 标准中,auto
关键字只能用于声明变量,不能用于函数参数、函数返回值、类成员等。auto
关键字的用法得到了扩展,可以用于函数返回值和 lambda 表达式中的形参类型推导。例如:
auto func(int x, double y) -> decltype(x + y) {
return x + y; // 推导返回值类型为 double
}
auto lambda = [](int x, int y) -> decltype(x + y) {
return x + y; // 推导形参类型和返回值类型为 int
};
需要注意的是,C++11 标准中的 auto
推导出来的类型都是变量本身的类型,而不是变量指针或引用的类型。如果需要使用指针或引用类型,需要显式指定类型,例如:
auto& ref = i; // 推导出 ref 的类型为 int&
auto* ptr = &i; // 推导出 ptr 的类型为 int*
const auto& cref = i;// 推导出 cref 的类型为 const int&
#include<iostream>
#include<typeinfo>
using namespace std;
auto max(int x,int y)
{
return x>y?x:y;
}
int main()
{
//auto变量必须在定义时初始化
auto a1 = 3;
auto a2{32};
//定义在一个auto序列的变量必须始终推导成同一类型
auto a3 = 1,a4= 3,a5{2};
//如果初始化表达式是引用或const,则去除引用或const语义(auto不管&和const)
int a6 = 1,&ra1= a6;
auto a7{ra1};
cout<<typeid(a7).name()<<endl;
// 如果auto关键字带上&号,则不去除引用或const语义
auto& ra2 = ra1;
cout<<"&ra1:"<<&ra1<<endl<<"&a6:"<<&a6<<endl<<"&ra2:"<<&ra2<<endl;
//初始化表达式为数组时,auto关键字推导类型为指针
int arr1[3]{1,3,4};
auto a8 = arr1;
cout<<typeid(a8).name()<<endl;
//若表达式为数组且auto带上&,则推导类型为数组类型
auto& a9 =arr1;
cout<<typeid(a9).name()<<endl;
// C++14中,auto可以作为函数的返回值类型和参数类型
cout<<max(a1,a2)<<endl;
return 0;
}
decltype
在编译时期推导一个表达式的类型,而不用初始化,其语法格式像sizeof
是由两个单词合并而成的:decltype
= decl
+ type
。
其中,decl
是 declare
的缩写,意为“声明”,表示该关键字可以用于推导表达式的类型而不需要实际执行该表达式。而 type
则是类型的意思,表示该关键字用于推导表达式的类型。
因此,decltype
的含义可以理解为“推导声明类型”。它可以用于推导表达式的类型,以及获取表达式的类型而不需要实际执行该表达式。
#include<iostream>
#include<typeinfo>
using namespace std;
int fun1(){return 10;}
auto fun2(){return 'g';}//C++14
int main()
{
decltype(fun1()) x;//int x;
decltype(fun2())y =fun2();//char y;
cout<<typeid(x).name()<<endl;
cout<<typeid(y).name()<<endl;
return 0;
}
typeid
C++ 关键字 typeid
是由两个单词合并而来的:type
+ identifier,其中,type
是类型的意思,表示该关键字用于获取表达式的类型信息。而 identifier
则是标识符的意思,表示该关键字用于获取表达式的唯一标识符。typeid用法是用于获取表达式的类型信息,其语法如下:
typeid(expression)
其中,expression
是需要获取类型信息的表达式,可以是任何表达式,包括变量、函数、类等。
typeid
返回一个 std::type_info
类型的对象,该对象可以用于获取表达式的类型信息,例如:
#include <iostream>
#include <typeinfo>
int main() {
int i = 1;
const std::type_info& ti = typeid(i);
std::cout << "Type of i is " << ti.name() << std::endl;
return 0;
}
该程序会输出 Type of i is int
,表示变量 i
的类型是 int
。
需要注意的是,typeid
返回的类型信息是在编译时确定的,而不是运行时确定的。如果表达式的类型是多态类型(即该类型有虚函数),则 typeid
返回的是表达式的静态类型,而不是动态类型。如果需要获取表达式的动态类型信息,可以使用 dynamic_cast
。
type_info
std::type_info
是 C++ 标准库中的一个类型信息类,位于 <typeinfo>
头文件中。它可以用于获取类型的信息,包括类型的名称、是否为多态类型等。
std::type_info
类的对象可以通过 typeid
关键字获取,例如:
#include <iostream>
#include <typeinfo>
int main() {
int i = 1;
const std::type_info& ti = typeid(i);
std::cout << "Type of i is " << ti.name() << std::endl;
return 0;
}
在上面的例子中,std::type_info
类型的对象 ti
是通过 typeid
关键字获取的,它表示变量 i
的类型信息。ti.name()
方法可以返回类型的名称,输出结果为 int
。
std::type_info
类还提供了其他方法,例如:
bool operator==(const std::type_info& rhs) const
:比较两个类型信息对象是否相等。bool operator!=(const std::type_info& rhs) const
:比较两个类型信息对象是否不相等。bool before(const std::type_info& rhs) const
:比较两个类型信息对象的地址是否按照字典序排列。
需要注意的是,std::type_info
类型的对象通常是不能被拷贝或赋值的,因此通常使用常量引用方式获取类型信息对象。此外,由于 std::type_info
类型的对象是在编译时确定的,因此它不能用于运行时的类型识别,如果需要运行时的类型识别,可以使用多态类型和 RTTI(运行时类型识别)技术。