c++11--类型自动推导

发布时间:2023年12月24日

1.自动类型推断
1.1.auto
a.auto声明变量的类型必须由编译器在编译时期推导而得。

int main(){
	double foo();
	auto x = 1;//x类型为int
	auto y = foo();// y类型为double
	auto z;// err
	return 0;
}

b.auto声明得变量必须被初始化。
c.针对指针和引用
推导类型是指针类型时,可以使用auto或auto*形式。
推导类型是引用类型时,必须使用auto&形式。

int main()
{
	int x;
	auto p = &x;//int*
	auto* p2 = &x;//int*
	auto& q = x;// int&
	auto qq = x;// int 
}

d.针对类型修饰符const 和 volatile
采用auto&形式时,若右边表达式含义const属性,结果类型也含const属性。若没有,则不含。
采用auto形式时,结果类型不会包含const属性。但可通过const auto自行添加。
结果类型不会包含volatile属性。但可通过volatile auto自行添加。

int main()
{
	auto i = 1;//int
	const auto ii = 1;//const int
	auto& ci = 1;//const int&
	volatile int p = 1;
	auto pp = p;// int
	volatile ppp = p;//volatile int
	
	const int ci = 1;
	const int* const cp = &ci;
	auto t = cp;//const int*。舍弃的const是修饰cp自身的。const int中的const不属于cp,会作为指针指向整体推断出来。
}

e.一次采用auto定义多个变量场景

int main()
{
	int a;
	auto * p = &a, q = a;// p为int*,q为int
	auto qq = a, t = 1.1f;// err。qq =a中auto被推断为int。t=1.1f中auto又被推断为float。
}

e.1.采用auto,一行定义多个变量,多个变量共享auto,其余的类型修饰符各自独立。如修饰p的*对q不起作用。
e,2,采用auto,一行定义多个变量,每个变量定义时推导的auto应该类型一致。qq,t推导的auto不一致,引发了编译报错。
f.不可用场景

#include <iostream>
using namespace std;
void fun(auto x = 1){} // err。auto不可用于修饰函数形参。
struct str{
	auto var = 10;// err。auto不可用于修饰类型非静态成员字段。
};
int main(){
	auto z[3] = {1,2,3};//err。auto不可用于修饰数组。
	std::vector<auto> v = {1};//auto不可用于作为实例化模板的模板参数。
}

1.2.decltype

#include <typeinfo>
#include <iostream>
using namespace std;

int main()
{
    int i;
    decltype(i) j = 0;
    cout << typeid(j).name() << endl;

    float a;
    double b;
    decltype(a+b) c;
    cout << typeid(c).name() << endl;
    return 0;
}

在这里插入图片描述
(1).decltype的类型推导基于表达式,类型是表达式的结果类型。auto基于初始化时的初始值推导类型。
(2).decltype的类型推导发生在编译时,auto也是。
(3).实例

#include <iostream>

// int
// const int

// int&
// int&&
// const int&
// const int&&

// int*
// const int*
// const int* const

int fun1() {
    return 1;
}
const int fun2() {
    return 1;
}
int a = 0;
const int ca = 1;
int& fun3() {
    a = 1;
    return a;
}
int&& fun4() {
    a = 1;
    return std::move(a);
}
const int& fun5(){
    return 1;
}
const int&& fun6(){
    return 1;
}
int* fun7(){
    return &a;
}
const int* fun8(){
    return &ca;
}
const int* const fun9(){
    return &ca;
}

int main()
{
    decltype (fun1) a1;
    decltype (fun2) a2;
    decltype (fun3) a3;
    decltype (fun4) a4;
    decltype (fun5) a5;
    decltype (fun6) a6;
    decltype (fun7) a7;
    decltype (fun8) a8;
    decltype (fun9) a9;
    return 0;
}

上述a1~a9推断所得类型将严格和表达式返回类型一致,它们是int、const int、int&、int&&、const int&、const int&&、int*、const int*、const int* const。

1.3.追踪返回类型
(1). 实例

template<typename T1, typename T2>
auto Sum(T1& t1, T2& t2) -> decltype(t1+t2){
	return t1+t2;
}

auto func() -> int
{
	return 1;
}

上述实例利用追踪返回类型定义函数,追踪返回类型也可用于函数类型声明。
(2).可利用追踪返回类型简化复杂类型定义

#include <type_traits>
#include <iostream>
using namespace std;
int (*(*pf())())(){
    return nullptr;
}

auto pf1() -> auto (*)() -> int (*)(){
    return nullptr;
}

int main(){
    cout << is_same<decltype(pf), decltype(pf1)>::value << endl;
    return 0;
}

在这里插入图片描述

文章来源:https://blog.csdn.net/x13262608581/article/details/135178139
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。