Android C++系列:C++最佳实践6 constexpr与decltype

简介: 上一篇介绍了const关键字,主要修饰变量,起到不可改变的常量作用。有一种值不会改变并且在编译过程就能得到计算结果的表达式我们称为常量表达式。

image.png


1. 背景


上一篇介绍了const关键字,主要修饰变量,起到不可改变的常量作用。有一种值不会改变并且在编译过程就能得到计算结果的表达式我们称为常量表达式


字面值属于常量表达式,用常量表达式初始化的const对象也是常量表达式:


const int MAX = 100;//常量表达式
const int MAX_TIME = MAX * 60;//常量表达式
int size = 30;//不是常量表达式
const int size2 = getSize();//不是常量表达式


一个对象或者表达式是不是常量表达式由它的数据类型和初始值共同决定,但是在一些复杂的系统中,我们难以分辨一个初始值是不是常量表达式。如何让编译器帮助我们判断是否是常量表达式呢?


2. constexpr


C++11中,引入了关键字constexpr,允许将变量声明为constexpr类型以便由编译器来验证变量的值是否是常量表达式。

声明为constexpr的变量一定是一个常量,而且必须用常量表达式初始化:


constexpr int i = 200;
constexpr int j = i + 100;
constexpr int size = getSize();//getSize必须是constexpr函数


constexpr除了修饰变量还可以修饰函数,这种函数必须是编译时就可以计算到结果。


2.1 constexpr限制


常量表达式的值需要在编译时就得到计算,所以对声明constexpr时用到的类型必须有所限制。


把比较简单,值显而易见,容易计算的类型成为“字面值类型”。算术类型,引用类型和指针都属于字面值类型。


指针和引用都能定义成constexpr,但是它们的初始值必须是nullptr或者0,或者是存储于某个固定地址中的对象。


函数体内定义的变量一般不是存放在固定地址中,因此constexpr指针不能指向函数体内定义的指针。


constexpr声明中如果定义了指针,限定符constexpr仅对指针有效,与指针所指的对象无关。


3. decltype类型指示符


当我们希望从表达式的类型推断出要定义的变量的类型,但是不想用这个表达式的值初始化变量,这个时候就要用到了C++11引入的类型说明符decltype,它的作用是选择并返回操作数的数据类型:


decltype(fun()) i = x;//i的类型就是函数fun的返回类型


编译器分析fun表达式并得到它的类型,但是不进行实际调用。


3.1 引用在decltype的特殊之处


如果decltype使用的表达式不是一个变量,则decltype返回表达式结果对应的类型。有时有些表达式向decltype返回一个引用类型。这时意味着表达式的结果对象能作为一条赋值语句的左值。


如果表达式的内容是解引用操作,decltype将得到引用类型。


引用和指针本身是C++比Java多的引用和指针已经加大了编程语言的复杂度,现在为它们增加了新特性更是让人眼花缭乱,但是如果不弄明白一是遇到实际问题不知道用什么办法解决;二是看别人代码的时候容易一头雾水。


4. 类型别名


C/C++还有为类型定义别名的能力。比如我们用到的uint_8之类跨平台类型都是基于typedef方式命名的。


传统的别名定义是使用typedef:typedef char uint_8


C++11中引入了一种新的方法,使用using方式:using Str = std::string


使用typedef给复合类型起名容易踩坑,比如:


typedef char *str;
const str cstr = 0;//cstr是指向char的常量指针
const str *s;//s是一个指针,它的对象是指向char的常量指针


const是对给定类型的修饰,str是指向char的指针,因此const str就是指向char的常量指针,而不是指向常量字符的指针。

我们往往直接做替换:


const char *cstr = 0;


理解成指向常量字符的指针。


5. 总结


本文作为const内容的延续,介绍了constexpr和decltype两种修饰符,以及类型别名的两种方式,以及typedef别名使用容易遇到的问题。

目录
相关文章
|
1月前
|
移动开发 监控 Android开发
Android & iOS 使用 ARMS 用户体验监控(RUM)的最佳实践
本文主要介绍了 ARMS 用户体验监控的基本功能特性,并介绍了在几种常见场景下的最佳实践。
220 11
|
5月前
|
安全 编译器 C++
C++一分钟之-编译时计算:constexpr与模板元编程
【6月更文挑战第28天】在C++中,`constexpr`和模板元编程用于编译时计算,提升性能和类型安全。`constexpr`指示编译器在编译时计算函数或对象,而模板元编程通过模板生成类型依赖代码。常见问题包括误解constexpr函数限制和模板递归深度。解决策略包括理解规则、编写清晰代码、测试验证和适度使用。通过实战示例展示了如何使用`constexpr`计算阶乘和模板元编程计算平方。
92 13
|
5月前
|
XML API 网络安全
【安卓】在安卓中使用HTTP协议的最佳实践
【安卓】在安卓中使用HTTP协议的最佳实践
116 4
|
2月前
|
安全 程序员 编译器
C++ 11新特性之auto和decltype
C++ 11新特性之auto和decltype
39 3
|
2月前
|
Java Android开发 C++
🚀Android NDK开发实战!Java与C++混合编程,打造极致性能体验!📊
在Android应用开发中,追求卓越性能是不变的主题。本文介绍如何利用Android NDK(Native Development Kit)结合Java与C++进行混合编程,提升应用性能。从环境搭建到JNI接口设计,再到实战示例,全面展示NDK的优势与应用技巧,助你打造高性能应用。通过具体案例,如计算斐波那契数列,详细讲解Java与C++的协作流程,帮助开发者掌握NDK开发精髓,实现高效计算与硬件交互。
133 1
|
6月前
|
NoSQL API Redis
最佳实践|如何使用c++开发redis module
本文将试着总结Tair用c++开发redis module中遇到的一些问题并沉淀为最佳实践,希望对redis module的使用者和开发者带来一些帮助(部分最佳实践也适用于c和其他语言)。
76643 0
|
4月前
|
Java Android开发 C++
🚀Android NDK开发实战!Java与C++混合编程,打造极致性能体验!📊
【7月更文挑战第28天】在 Android 开发中, NDK 让 Java 与 C++ 混合编程成为可能, 从而提升应用性能。**为何选 NDK?** C++ 在执行效率与内存管理上优于 Java, 特别适合高性能需求场景。**环境搭建** 需 Android Studio 和 NDK, 工具如 CMake。**JNI** 构建 Java-C++ 交互, 通过声明 `native` 方法并在 C++ 中实现。**实战** 示例: 使用 C++ 计算斐波那契数列以提高效率。**总结** 混合编程增强性能, 但增加复杂性, 使用前需谨慎评估。
140 4
|
3月前
|
JSON Android开发 C++
Android c++ core guideline checker 应用
Android c++ core guideline checker 应用
|
3月前
|
JSON Android开发 数据格式
Android c++ core guideline checker 应用问题之JSON compilation database的定义如何解决
Android c++ core guideline checker 应用问题之JSON compilation database的定义如何解决
|
3月前
|
IDE 开发工具 Android开发
Android c++ core guideline checker 应用问题之clang-tidy 检查后发现的问题如何解决
Android c++ core guideline checker 应用问题之clang-tidy 检查后发现的问题如何解决