C++17中的内联变量

news2024/11/30 6:36:54

      在C++11中:
      (1).声明为constexpr的函数隐式地是内联函数;
      (2).deleted函数隐式地是一个内联函数。
      在内联函数中:
      1.所有函数定义中的函数局部静态对象(function-local static object)在所有翻译单元之间共享(它们都引用一个翻译单元中定义的同一对象)。
      2.所有函数定义中定义的类型在所有翻译单元中也相同。
      inline关键字的最初目的是向优化器指示函数的内联替换优先于函数调用,即不执行函数调用CPU指令将控制权转移到函数体,而是执行函数的副本即函数体在不生成调用的情况下执行。这避免了函数调用(传递参数并检索结果)产生的开销,但可能会导致更大的可执行文件,因为函数的代码必须重复多次。
      由于关键字inline的含义是非绑定的(non-binding),因此编译器可以自由地对任何未标记为内联的函数使用内联替换,并且可以自由地生成对任何标记为内联的函数的函数调用。

      C++17引入了内联变量,即允许在多个文件中定义的变量。内联变量的工作方式与内联函数类似,并且具有相同的要求(编译器必须能够在使用该变量的任何地方看到相同的完整定义)。

      内联说明符(inline specifier)在具有静态存储持续时间(static storage duration)的变量(静态类成员或命名空间范围内的变量)的decl-specifier-seq(declaration specifiers)中使用时,将该变量声明为内联变量。
      声明为constexpr的静态成员变量(但不是命名空间范围内的变量)隐式地是内联变量

      C++的两种链接方式:外部链接(External Linking)和内部链接(Internal Linking)
      1.外部链接:函数或变量可以在其它翻译单元中使用。默认情况下,在C++中定义的函数和全局变量都具有外部链接属性。
      2.内部链接:函数或变量只能在定义它的翻译单元中使用。

      内联函数或内联变量(inline function or inline variable)具有以下属性:
      1.内联函数或内联变量的定义必须在访问它的翻译单元(translation unit,源代码文件如.cpp)中可访问
      2.具有外部链接(external linkage)(例如未声明为静态)的内联函数或内联变量具有以下附加属性:
      (1).程序中可能存在多个内联函数或内联变量的定义,只要每个定义出现在不同的翻译单元中(different translation unit)并且(对于非静态内联函数和内联变量)所有定义都是相同的。例如,内联函数或内联变量可以定义在包含在多个源文件中的头文件中。
      (2).它必须在每个翻译单元中声明为内联。
      (3).每个翻译单元都有相同的地址(same address).

      命名空间范围内的内联const变量默认具有外部链接(与非内联、非易失性、const限定(non-inline non-volatile const-qualified)变量不同)。

      因为函数的关键字inline的含义开始意味着"允许多个定义"而不是"首选内联",所以该含义被扩展到内联变量。在现代C++中,内联已演变为"允许多个定义"的意思

      内联变量消除了将C++代码打包为仅含头文件库的主要障碍(Inline variables eliminate the main obstacle to packaging C++ code as header-only libraries)。

      内联变量在未声明为静态时具有外部链接.
      如果内联变量有多个定义,编译器会在需要时选择其中一个定义.
      与内联函数不同,内联变量可以具有静态存储持续时间(static storage duration)。如果内联变量是在类范围内定义的,则它的行为类似于静态成员变量。此类成员变量可以在类内部初始化
      内联变量在所有翻译单元中具有相同的内存地址。
      C++17允许在不同的翻译单元中对内联变量进行多个定义,并且每个翻译单元将拥有自己的变量副本。
      内联变量默认具有外部链接。如果我们想定义一个具有内部链接的内联变量,我们可以使用静态说明符。
      当我们在全局变量上使用inline关键字时,我们不需要在其他地方将它们定义为"extern"。对于静态成员变量,我们不需要在类外部定义它们
      根据一次定义原则(ODR, One Definition Rule),一个变量或实体的定义只能出现在一个编译单元内----除非该变量或实体被定义为inline的。

      内联变量和thread_local:通过使用thread_local你可以为每个线程创建一个内联变量

      注意:
      (1).如果具有外部链接的内联函数或内联变量在不同的翻译单元中定义不同,则程序格式错误(ill-formed),无需诊断。
      (2).内联说明符不能与块作用域(在另一个函数内)的函数或变量声明一起使用。
      (3).内联说明符无法重新声明已在翻译单元中定义为非内联的函数或非内联的变量。
      (4).隐式生成的(implicitly-generated)成员函数以及在其第一个声明中声明为默认的(defaulted)任何成员函数都是内联的,就像类定义中定义的任何其他函数一样。
      (5).如果在不同的翻译单元中声明内联函数,则每个翻译单元末尾的累积默认参数集必须相同(the accumulated sets of default arguments must be the same at the end of each translation unit)。

      以下为测试代码:

      1. inline.hpp:此头文件会被多个.cpp文件include,若不带inline,会编译不过

class InlineVariable {
public:
	inline static int var{ 10 }; // 不带inline,则只能在类外初始化;即使在类外初始化,如果被多个cpp文件包含也会error;带inline后,即使被多个cpp文件包含也OK
	const char* csdn_addr{ "https://blog.csdn.net/fengbingchun/" };
	static constexpr int num{ 6 }; // 对于静态成员,constexpr修饰符隐含着inline,等价于: inline static constexpr int num{ 6 };

	inline static std::string name{ "Messy_Test" }; // 整个程序中只有一个
	inline static thread_local int count{ 1 }; // 每个线程有一个
	std::string city{ "BeiJing" }; // 每个实例有一个
};

inline InlineVariable inline_variable; // 不带inline,则会报重复定义;带inline后,即使被多个cpp文件包含也OK
inline thread_local InlineVariable inline_variable2; // 每个线程一个对象

      2. inline.cpp:

int test_inline_variable_1()
{
	std::cout << "var: " << InlineVariable::var << "\n";
	std::cout << "csdn addr: " << inline_variable.csdn_addr << "\n";
	std::cout << "num: " << InlineVariable::num << "\n";

	return 0;
}

      执行结果如下图所示:

      GitHub:https://github.com/fengbingchun/Messy_Test

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1348311.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

实时交通标志检测和分类(代码)

交通标志检测和分类技术是一种基于计算机视觉和深度学习的先进技术&#xff0c;能够识别道路上的各种交通标志&#xff0c;并对其进行分类和识别。这项技术在智能交通系统、自动驾驶汽车和交通安全管理领域具有重要的应用前景。下面我将结合实时交通标志检测和分类的重要性、技…

【STM32】SPI通信

1 SPI通信 SPI&#xff08;Serial Peripheral Interface&#xff0c;串行外设接口&#xff09;是由Motorola公司开发的一种通用数据总线 四根通信线&#xff1a;SCK&#xff08;Serial Clock&#xff0c;串行时钟&#xff09;、MOSI&#xff08;Master Output Slave Input&am…

【MyBatis】操作数据库——入门

文章目录 为什么要学习MyBatis什么是MyBatisMyBatis 入门创建带有MyBatis框架的SpringBoot项目数据准备在配置文件中配置数据库相关信息实现持久层代码单元测试 为什么要学习MyBatis 前面我们肯定多多少少学过 sql 语言&#xff0c;sql 语言是一种操作数据库的一类语言&#x…

BLE Mesh蓝牙组网技术详细解析之Lower Transport Layer下传输层(四)

目录 一、什么是BLE Mesh Lower Transport Layer下传输层&#xff1f; 二、未分段消息 2.1 未分段接入层消息 2.2 未分段控制层消息 三、分段消息 3.1 超过多少个字节需要分段&#xff1f; 3.2 分段接入层消息 3.3 分段控制层消息 3.4 分段确认消息 3.5 分段和重组流程…

按行依次处理数据的文件操作(C语言版)

按行依次处理数据的文件操作(C语言版) 这段代码的目的是处理多个文件&#xff0c;为每个文件创建一个新文件&#xff0c;将以 ‘r’ 开头的行添加 “./” 前缀&#xff0c;并将修改后的内容写入新文件。在main函数中&#xff0c;通过调用process函数&#xff0c;逐个处理了一系…

牛客网SQL训练5—SQL大厂面试真题

文章目录 一、某音短视频1.各个视频的平均完播率2.平均播放进度大于60%的视频类别3.每类视频近一个月的转发量/率4.每个创作者每月的涨粉率及截止当前的总粉丝量5.国庆期间每类视频点赞量和转发量6.近一个月发布的视频中热度最高的top3视频 二、用户增长场景&#xff08;某度信…

[react]脚手架create-react-app/vite与reac项目

[react]脚手架create-react-app/vite与reac项目 环境问题描述create-react-app 脚手架根据脚手架修改项目结构安装脚手架注入配置文件-config文件夹package.json文件变更删除 serviceWorker.js新增reportWebVitals.js文件更新index.js文件 脚手架creat-react-app 缺点 vite 脚手…

数据结构期末复习(2)链表

链表 链表&#xff08;Linked List&#xff09;是一种常见的数据结构&#xff0c;用于存储一系列具有相同类型的元素。链表由节点&#xff08;Node&#xff09;组成&#xff0c;每个节点包含两部分&#xff1a;数据域&#xff08;存储元素值&#xff09;和指针域&#xff08;指…

MyBatis多表映射

1. 多表映射概念 MyBatis 思想是&#xff1a;数据库不可能永远是你所想或所需的那个样子。 我们希望每个数据库都具备良好的第三范式或 BCNF 范式&#xff0c;可惜它们并不都是那样。 如果能有一种数据库映射模式&#xff0c;完美适配所有的应用程序查询需求&#xff0c;那就太…

【FileZilla的安装与使用(主动与被动模式详解,以及如何利用FileZilla搭建FTP服务器并且进行访问)】

目录 一、FileZilla介绍 1.1 简介 1.2 重要信息和功能 二、FileZilla的安装与使用 2.1 FileZilla服务端安装与配置 2.1.1 安装步骤 2.1.2 新建组 2.1.3 新建用户 2.1.4 新建目录 2.1.5 权限分配 &#xff08;1&#xff09;用户Milk权限分配 &#xff08;2&#xff…

HikvisionCamera开发-萤石云RTMP协议获取视频流

RTMP/RTSP&#xff08;实时流传输协议&#xff09;是一种网络协议&#xff0c;旨在用于传输音频和视频数据。本文将介绍如何在HikvisionCamera二次开发中如何通过RTMP协议获得实时视频流&#xff0c;使用到的摄像头为POE供电的海康威视-臻全彩款&#xff0c;以及套餐内配套录像…

JMeter使用

目录 启动JMeter 创建线程组 设置线程参数 设置http请求参数 ​编辑 创建查看结果树(显示成功/失败多少以及返回结果等信息) 创建聚合报告(显示响应时间、吞吐量、异常数等信息) 点击上方的执行按钮即可开始压力测试 结果树显示 聚合报告结果显示 启动JMeter 在JMete…

【NLP论文】03 基于 jiagu 的情感分析

本篇是NLP论文系列的最后一篇&#xff0c;主要介绍如何计算情感分析结果&#xff0c;并将其融入到XX评价体系和物流关键词词库&#xff0c;之前我已经写了两篇关于情感分析的文章&#xff0c;分别是 SnowNLP 和 Cemotion 技术&#xff0c;最终我才用了 jiagu 来写我的论文&…

机器人中的数值优化之线性共轭梯度法

欢迎大家关注我的B站&#xff1a; 偷吃薯片的Zheng同学的个人空间-偷吃薯片的Zheng同学个人主页-哔哩哔哩视频 (bilibili.com) 本文ppt来自深蓝学院《机器人中的数值优化》 目录 1.无约束优化方法对比 2.Hessian-vec product 3.线性共轭梯度方法的步长​编辑 4.共轭梯度…

mac上使用Navicat Premium 在本地和生产环境中保持数据库同步

Navicat Premium 是一款功能强大的数据库管理和开发工具&#xff0c;支持多种数据库系统&#xff0c;如 MySQL、Oracle、SQL Server 等。作为程序员&#xff0c;我深知在开发过程中需要一款方便、高效的数据库管理工具来提升工作效率。而 Navicat Premium 正是这样一款不可多得…

Spring Boot学习随笔- Jasypt加密数据库用户名和密码以及解密

学习视频&#xff1a;【编程不良人】2021年SpringBoot最新最全教程 第十九章、Jasypt加密 Jasypt全称是Java Simplified Encryption&#xff0c;是一个开源项目。 Jasypt与Spring Boot集成&#xff0c;以便在应用程序的属性文件中加密敏感信息&#xff0c;然后在应用程序运行…

怎么解决 Nginx反向代理加载速度慢?

Nginx反向代理加载速度慢可能由多种原因引起&#xff0c;以下是一些可能的解决方法&#xff1a; 1&#xff0c;网络延迟&#xff1a; 检查目标服务器的网络状况&#xff0c;确保其网络连接正常。如果目标服务器位于不同的地理位置&#xff0c;可能会有较大的网络延迟。考虑使用…

从0到1快速入门ETLCloud

一、ETLCloud的介绍 ETL是将业务系统的数据经过抽取&#xff08;Extract&#xff09;、清洗转换&#xff08;Transform&#xff09;之后加载&#xff08;Load&#xff09;到数据仓库的过程&#xff0c;目的是将企业中的分散、凌乱、标准不统一的数据整合到一起&#xff0c;为企…

【C#】知识点实践序列之Lock的输出多线程信息

大家好&#xff0c;我是全栈小5&#xff0c;欢迎来到《小5讲堂之知识点实践序列》文章。 2023年第2篇文章&#xff0c;此篇文章是C#知识点实践序列之Lock知识点&#xff0c;博主能力有限&#xff0c;理解水平有限&#xff0c;若有不对之处望指正&#xff01; 本篇在Lock锁定代码…

【力扣题解】P700-二叉搜索树中的搜索-Java题解

&#x1f468;‍&#x1f4bb;博客主页&#xff1a;花无缺 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! 本文由 花无缺 原创 收录于专栏 【力扣题解】 文章目录 【力扣题解】P700-二叉搜索树中的搜索-Java题解&#x1f30f;题目描述&#x1f4a1;题解&#x1f…