为什么使用auto:有些情况下可能不知道需要实际类型怎么设定,或者类型写起来特别复杂,使用auto
#include
#include
int main()
{
short a = 32670;
short b = 32670;
// c如果给成short,会造成数据丢失,如果能够让编译器根据a+b的结果推导c的实际类型,就不会存在问题
short c = a + b;
std::map<std::string, std::string> m{{"apple", "苹果"}, {"banana","香蕉"}};
// 使用迭代器遍历容器, 迭代器类型太繁琐
std::map<std::string, std::string>::iterator it = m.begin();
while(it != m.end())
{
cout<<it->first<<" "<<it->second<<endl;
++it;
}
return 0;
}
auto的使用
int TestAuto()
{
return 10;
}
int main() {
int a = 10;
auto b = a;
auto c = 'a';
auto d = TestAuto();
short aa = 32670;
short bb = 32670;
auto cc = aa + bb; //自动推导
cout << typeid(b).name() << endl;//int
cout << typeid(c).name() << endl;//char
cout << typeid(d).name() << endl;//int
//auto e; 无法通过编译,使用auto定义变量时必须对其进行初始化
return 0;
}
int main() {
int x = 10;
auto a = &x;
auto* b = &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;//x == *a == *b == c == 20
*b = 30;//x == *a == *b == c == 30
c = 40; //x == *a == *b == c == 40
return 0;
}
当在同一行声明多个变量时,这些变量必须是相同的类型,否则编译器将会报错 。因为编译器实际只对第一个类型进行推导,然后用推导出来的类型定义其他变量。
void TestAuto()
{
auto a = 1, b = 2;
auto c = 3, d = 4.0; // 该行代码会编译失败,因为c和d的初始化表达式类型不同 对于编译器有二义性,没法推导
}
// 此处代码编译失败,auto不能作为形参类型,因为编译器无法对a的实际类型进行推导
void TestAuto(auto var=1){}
void TestAuto(){
auto var=10;//无法通过编译
}
void TestAuto(){
int arr[] = {1,1,1};
//auto b[] = { 2,2,2};//auto不能直接用来声明数组
}
vector<auto> x={1};// 无法通过编译
auto用于推导变量类型,而decltype则用于推导表达式类型,只用于编译器分析表达式的类型,表达式实际不会进行运算。
decltype(e)推导并返回操作数对象e的数据类型,但不实际进行调用或运算。
decltype会保留表达式的引用。
const int &i = 1;
int a = 2;
decltype(i) b = 2; //b是const int&
1.推演表达式类型作为变量的定义类型
#include
using namespace std;
int main() {
short a = 32670;
short b = 32670;
// 用decltype推演a+b的实际类型,作为定义c的类型
decltype(a + b) c;
cout << typeid(c).name() << endl; // int
return 0;
}
void* GetMemory(size_t size)
{
return malloc(size);
}
int main() {
// 如果没有带参数,推导函数的类型
cout << typeid(decltype(GetMemory)).name() << endl; // void * __cdecl(unsigned int)
// 如果带参数列表,推导的是函数返回值的类型,注意:此处只是推演,不会执行函数
cout << typeid(decltype(GetMemory(0))).name() <<endl; // void *
return 0;
}
追踪返回类型
返回类型后置:在函数名和参数列表后面指定返回类型
template<typename T1,typename T2>
auto sum(const T1& t1,const T2 &t2)->decltype(t1+t2){
return t1+t2;
}
错误案例
//情况1
template<typename T1,typename T2>
return_value sum(const T1& t1,const T2 &t2){// t1和t2类型不确定,无法推导出return_value类型
return t1 + t2;
}
//情况2
template<typename T1,typename T2>
decltype(t1 + t2) sum(const T1& t1,const T2 &t2){// t1和t2类型不确定,在decltype(t1 +t2)推导时,t1和t2尚未定义,就会编译出错
return t1 + t2;
}
返回值后置类型语法就是为了解决函数返回制类型依赖于参数但却难以确定返回值类型的问题。