0

C++11系列—类型推导

 2 years ago
source link: https://blog.51cto.com/u_14156525/5235378
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

C++11系列—类型推导

原创

小杰编程 2022-04-21 09:01:16 博主文章分类:C++11系列文章 ©著作权

文章标签 c++ 初始化 泛型 文章分类 C/C++ 编程语言 阅读数182

大家好,我是小杰。

如果读完这篇感觉到有用的知识增加了,不妨点个赞和在看,鼓励一下

auto类型推导

C++旧标准:

具有自动存储的局部变量

auto int i = 0 //C++98

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

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

auto基本用法

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 推导规则

黄金法则

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

auto 的限制

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

auto 适用场景

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

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

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

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 基本用法

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 推导规则

黄金法则:

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

decltype 适用场景

decltype适用于泛型相关

场景一:

标准库中有些类型的定义

typedef decltype(nullptr) nullptr_t
typedef decltype(sizeof(0)) size_t
`

场景二:

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

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

场景三:

template<class ContainerT>
class Foo
{
decltype(ContainerT().begin()) it_;
public:
void func(ContarinerT& container)
{
it_ = container.begin();
}
// ...
}

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

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

int & foo(int& i);
float foo(float& f)
template<typename T>
auto fun(T& val) -> decltype(foo(val))
{
return foo(val);
}

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

  • 收藏
  • 评论
  • 分享
  • 举报

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK