服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C/C++ - C++11系列学习之类型推导

C++11系列学习之类型推导

2022-11-16 15:55小杰编程 C/C++

这篇文章主要介绍了C++11系列学习之类型推导,文章基于C++的相关资料展开对主题的详细内容介绍,具有一定的参考价值需要的小伙伴可参考一下

auto类型推导

C++旧标准:

具有自动存储的局部变量

?
1
auto int i = 0 //C++98

实际上我们一般不这样写,因为非static变量默认就是具有自动存储的局部变量

C++11:

让编译器自动推断出这个变量的类型,而不需要显式指定类型

auto基本用法

演示:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
auto x = 5 //x --> int
auto pi = new auto(1) //pi --> int*
const auto *v = &x, u = 6 //v --> const int* 、 u --> const int
static auto y = 0.0 //y --> double
int x = 0
auto * a = &x //a --> int* , auto为int
auto b = &x //b --> int* , auto 为 int*
auto c = x //c --> int& , auto为int
auto d = c //d --> int , auto为int
const auto e = x //e --> const int
auto f = e //f --> int
const auto& g = x //g --> const int&
auto& h = g //h --> const int&

上面就是通常会出现的所有情况,其实可以类比模板参数自动推导

auto 不能用于函数参数

auto 推导规则

黄金法则

  • 当不声明为指针或引用时,auto的推到结果和初始化表达式抛弃引用和cv限定符(cosnt 和 volatile,下同)后类型一致
  • 当声明为指针或引用时,auto的推到结果将保持初始化表达式的cv属性

auto 的限制

  • 不能用于函数参数
  • 不支持非静态成员变量的初始化
  • main函数中auto不会被推导为数组类型,而是指针类型

auto 适用场景

场景一:for循环中用来遍历容器

?
1
2
3
for(auto it = resultMap.begin(); it != resultMap.end(); ++i){
//do something
}

场景二:用于不知道如何定义变量,多与泛型有关

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Foo{
public:
static int get(void)
{
return 0;
}
};
class Bar{
public:
static const char* get(void)
{
return "0";
}
};
template<class A>
void func(void)
{
auto val = A::get();
// ...
}

decltype 类型推导

decltype( exp )

exp 表示一个表达式
从格式上来看,decltype像sizeof ,但其用来在编译时推导出一个表达式的类型

decltype 基本用法

?
1
2
3
4
5
6
7
8
int x = 0
decltype(x) y = 1 //y -> int
decltype(x + y) z = 0 //z -> int
const int& i = x
decltype(i) j = y //j -> const int &
cosnt decltype(z) *p = &z //*p -> const int, p -> const int *
decltype(z) * pi = &z //*pi -> int , pi -> int*
decltype(pi) * pp = &pi //*pp -> int * ,pp -> int **

decltype和&结合的推导结果,与引用折叠规则有关,将在本系列后续中详细讲解

decltype 推导规则

黄金法则:

  • exp是标识符、类访问表达式,decltype(exp) 和exp的类型一致
  • exp是寒素调用,decltype(exp) 和返回值 的类型一致
  • 其他情况,若exp是个左值,则 ecltype(exp) 是exp类型的左值引用,否则和exp类型一致

decltype 适用场景

decltype适用于泛型相关

场景一:

标准库中有些类型的定义

?
1
2
3
typedef decltype(nullptr) nullptr_t
typedef decltype(sizeof(0)) size_t
`

场景二:

通过变量表达式抽取变量类型实现简写

?
1
2
vector<int> v;
decltype(v):value_type i = 0

场景三:

?
1
2
3
4
5
6
7
8
9
10
11
template<class ContainerT>
class Foo
{
decltype(ContainerT().begin()) it_;
public:
void func(ContarinerT& container)
{
it_ = container.begin();
}
// ...
}

auto 和 decltype结合——返回类型后置

即通过两个结合起来,使得语法更加灵活便捷

?
1
2
3
4
5
6
7
int & foo(int& i);
float foo(float& f)
template<typename T>
auto fun(T& val) -> decltype(foo(val))
{
return foo(val);
}

小结

autodecltype的出现不仅弥补了C++旧版标准的不足,也大大解放了开发人员的生产力,提升了效率。但是我们在使用的时候仍然需要注意,不能滥用,否则会出现我们期望得到的类型和最终程序的类型不一致,导致一些意想不到的BUG,给我维护增加了成本,适用和巧用才是正解

到此这篇关于C++11系列学习之类型推导的文章就介绍到这了,更多相关C++11类型推导内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://blog.51cto.com/u_14156525/5235378

延伸 · 阅读

精彩推荐