类型别名的思考
随着程序越来越复杂,程序中用到的类型也越来越复杂,经常体现在:
- 类型难于拼写
- 含义不明确导致容易出错
#include <string>
#include <map>
int main()
{
std::map<std::string, std::string> m{ { "apple", "苹果" }, { "orange","橙子" }, {"pear","梨"} };
std::map<std::string, std::string>::iterator it = m.begin();
while (it != m.end())
{
//....
}
return 0;
}
std::map<std::string, std::string>::iterator 是一个类型,但是该类型太长了,特别容易写错。聪明的同学可能已经想到:可以通过typedef给类型取别名,比如:
#include <string>
#include <map>
typedef std::map<std::string, std::string> Map;
int main()
{
Map m{{"apple","苹果"},{"orange","橙子"},{"pear","梨"}};
Map::iterator it = m.begin();
while (it != m.end())
{
//....
}
return 0;
}
使用typedef给类型取别名确实可以简化代码,但是typedef有会遇到新的难题:
typedef char* pstring;
int main()
{
const pstring p1; // 编译成功还是失败?
const pstring* p2; // 编译成功还是失败?
return 0;
}
大家可以尝试在自己的编译器编译一下上述代码。
auto简介
在C++11中,引入了一个新特性–auto关键字,它可以实现变量类型自动推导,使代码更简洁、可读性更好,同时避免了代码中的类型定义和类型推断之间的不匹配问题。
- auto关键字的语法
auto关键字的语法比较简单,其格式为:
auto var_name = initial_value;
此处 var_name 为变量名,initial_value为赋予变量的初值,其中 auto为自动类型推导关键字。
使用auto关键字定义变量时,编译器会根据初始值的类型,自动推导出变量的类型。例如:
auto a = 10; //a为int类型
auto b = 1.5; //b为double类型
auto c = "hello"; //c为const char*类型
//typeid(变量).name()可用于推导变量的类型
cout << typeid(a).name() << endl;//int
cout << typeid(b).name() << endl;//double
cout << typeid(c).name() << endl;//char const *
值得一提的是,auto关键字常常与initializer列表结合使用,这样更能体现auto的特性。可以简化代码,减少代码量,同时也可以提高代码的可读性和可维护性。例如::
std::vector<int> vec = {1, 2, 3};
for(auto it = vec.begin(); it != vec.end(); ++it){
std::cout << *it << std::endl;
}
此处,auto关键字会自动推导出迭代器的类型,不用显式地进行类型定义和类型转换。
auto关键字的特性
- 使用auto定义变量时必须对其进行初始化,在编译阶段编译器需要根据初始化表达式来推导auto的实际类型。因此auto并非是一种“类型”的声明,而是一个类型声明时的“占位符”,编译器在编译期会将auto替换为变量实际的类型。
- auto与指针和引用可以结合起来使用。
but用auto声明指针类型时,用auto和auto*没有任何区别,但用auto声明引用类型时则必须加&。
int main()
{
int x = 10;
auto a = &x;
auto* b = &x;
auto& c = x;
cout << typeid(a).name() << endl;//int*
cout << typeid(b).name() << endl;//int*
cout << typeid(c).name() << endl;//int
*a = 20;
*b = 30;
c = 40;
return 0;
}
3.当在同一行声明多个变量时,这些变量必须是相同的类型,否则编译器将会报错,因为编译器实际只对第一个类型进行推导,然后用推导出来的类型定义其他变量。
void TestAuto()
{
auto a = 1, b = 2;
auto c = 3, d = 4.0; // 该行代码会编译失败,因为c和d的初始化表达式类型不同
}
- auto不能作为函数的参数
// 此处代码编译失败,auto不能作为形参类型,因为编译器无法对a的实际类型进行推导
void TestAuto(auto a)
{}
5.auto不能直接用来声明数组
void TestAuto()
{
int a[] = {1,2,3};
auto b[] = {4,5,6};//报错
}
6.为了避免与C++98中的auto发生混淆,C++11只保留了auto作为类型指示符的用法
7.auto在实际中最常见的优势用法就是跟以后会讲到的C++11提供的新式for循环,还有lambda表达式等进行配合使用。
以上就是关于C++的auto关键字的介绍,希望对大家C++语言的学习有所帮助。