C++17常量

nullptr

??nullptr出現的目的是為了替代NULL。在某種意義上來說,傳統會把NULL,0視為同一種東 西,這取決于編譯器如何定義NULL,有些編譯器會將定義為((void*)0),有些則會直接將其定義 為0。?

??????? C++不允許直接將void*隱式轉換到其他類型。但如果編譯器嘗試把NULL定義為((void*)0), 那么在下面這句代碼中:?

char *ch = NULL;

??????? 沒有了void*隱式轉換的C++只好將定義為0。而這依然會產生新的問題,將NULL定義成0,將導致C++中重載特性發生混亂。考慮下面這兩個函數:?

void foo(char*);

void foo(int);

????????那么foo(NULL)這個語句將會去調用foo(int),從而導致代碼違反直覺。?

??????? 為了解決這個問題,C++引入了關鍵字nullptr,專門用來區分空指針、0。而nullptr的類型 為nullptr_t,能夠隱式的轉換為任何指針或成員指針的類型,也能和他們進行相等或者不等的比較。 你可以嘗試使用clang++編譯下面的代碼:

#include <iostream>#include <type_traits>//*******1. nullptr******/
// C++17 引入了 std::nullptr_t 類型,它是一個空指針類型。
// 在 C++ 中,NULL 是一個宏,通常定義為 0 或 (void*)0。 
/*int main(){if(std::is_same<decltype(NULL), decltype(0)>::value){std::cout << "NULL is the same type as 0" << std::endl;}else{std::cout << "NULL is NOT the same type as 0" << std::endl;//NULL 和 0 在 C++ 中是不同的類型。}if(std::is_same<decltype(NULL), decltype((void*)0)>::value){std::cout << "NULL is the same type as (void*)0" << std::endl;}else{std::cout << "NULL is NOT the same type as (void*)0" << std::endl;//NULL 和 (void*)0 在 C++ 中是不同的類型。}if(std::is_same<decltype(NULL), std::nullptr_t>::value){std::cout << "NULL is the same type as std::nullptr_t" << std::endl;}else{std::cout << "NULL is NOT the same type as std::nullptr_t" << std::endl;//NULL 和 std::nullptr_t 在 C++ 中是不同的類型。}return 0;
}
*/

??????? 從輸出中我們可以看出,NULL不同于與nullptr,0。所以,請養成直接使用的習慣。 此外,在上面的代碼中,我們使用了decltype和std::is_same這兩個屬于現代C++的語法,簡 單來說decltype用于類型推導,而std::is_same用于比較兩個類型是否相同,我們會在后面 一節中詳細討論。

constexpr

??????? C++本身已經具備了常量表達式的概念,比如1+2, 3*4這種表達式總是會產生相同的結果并且沒 有任何副作用。如果編譯器能夠在編譯時就把這些表達式直接優化并植入到程序運行時,將能增加程序 的性能。一個非常明顯的例子就是在數組的定義階段:

// C++17 引入了 constexpr 關鍵字,它允許在編譯時計算常量表達式。
#include <iostream> 
#define LEN 10/*
int len_foo(){int i = 2;return i;
}constexpr int len_foo_constexpr() {return 5;
}constexpr int fibonacci(const int n) {return  n==1 || n == 2 ? 1 : fibonacci(n - 1) + fibonacci(n - 2);
}int main() {char arr_1[10];                 //合法char arr_2[LEN];                //非法    int len = 10;//char arr_3[len];                //非法const int len_2 = len + 1;constexpr int len_2_constexpr = 1+2+3;//char arr_4[len_2_constexpr];       //合法char arr_4[len_2];       //非法//char arr_5[len_foo()];             //非法char arr_6[len_foo_constexpr() + 1];   //合法std::cout << "fibonacci(10) = " << fibonacci(10) << std::endl; // 輸出 55//1, 1, 2, 3, 5, 8, 13, 21, 34, 55std::cout << "fibonacci(10) = " << fibonacci(10) << std::endl; // return 0;}
*/

????????上面的例子中char arr_4[len_2]可能比較令人困惑,因為len_2已經被定義為了常量

char arr_4[len_2]為什么仍然是非法的呢?這是因為C++標準中數組的長度必須是一個常量表達式,而對len_2于而言,這是一個const常數,而不是一個常量表達式,因此(即便這種行為在大部分編譯器中都支持,但是)它是一個非法的行為,我們需要使用接下來即將介紹的C++11引入的constexpr特性來解決這個問題;而對于arr_5來說,C++98之前的編譯器無法得知len_foo()在運行期實際上是返回一個常數,這也就導致了非法的產生。

????????注意,現在大部分編譯器其實都帶有自身編譯優化,很多非法行為在編譯器優化的加持下會變得合法,若需重現編譯報錯的現象需要使用老版本的編譯器。

??????? C++11提供了constexpr讓用戶顯式的聲明函數或對象構造函數在編譯期會成為常量表達式,這個關鍵字明確的告訴編譯器應該去驗證len_foo()在編譯期就應該是一個常量表達式。此外,修飾的函數可以使用遞歸:

constexpr int fibonacci(const int n) {return  n==1 || n == 2 ? 1 : fibonacci(n - 1) + fibonacci(n - 2);
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/82945.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/82945.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/82945.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

計算機網絡學習(九)——CDN

一、CDN CDN&#xff08;Content Delivery Network&#xff0c;內容分發網絡&#xff09;是一種通過分布式節點將內容更高效地傳遞給用戶的技術架構&#xff0c;廣泛應用于加速網站、視頻、下載、直播等業務。 CDN 是把內容放到離用戶最近的“高速公路入口”&#xff0c;提升訪…

Elasticsearch的寫入流程介紹

Elasticsearch 的寫入流程是一個涉及 分布式協調、分片路由、數據同步和副本更新 的復雜過程,其設計目標是確保數據一致性、可靠性和高性能。以下是寫入流程的詳細解析: 一、寫入流程總覽 二、詳細步驟解析 1. 客戶端請求路由 請求入口:客戶端(如 Java 客戶端、REST API)…

vue為什么點擊兩遍才把參數傳遞過去

先說一下場景&#xff0c;就是我把云服務器這個下拉選擇框分別初始化之后&#xff0c;然后點擊新建權限然后就打開了右側的抽屜式的對話框&#xff0c;頁面上那個文字信息是傳遞過來了。那個是正確的&#xff0c;但是我請求接口的時候&#xff0c;發現請求的接口的參數總是要慢…

java代碼性能優化

刷題過程中遇到的一些時間復雜度相同&#xff0c;但是常數因子的差距導致的性能差距&#xff0c;遇到持續更新 枚舉 VS contains 例如&#xff1a;判斷一個字符是不是元音 法一&#xff1a; if(ch a || ch e || ch i || ch o || ch u) 法二&#xff1a; Set<Charact…

OpenGL Chan視頻學習-9 Index Buffers inOpenGL

bilibili視頻鏈接&#xff1a; 【最好的OpenGL教程之一】https://www.bilibili.com/video/BV1MJ411u7Bc?p5&vd_source44b77bde056381262ee55e448b9b1973 函數網站&#xff1a; docs.gl 說明&#xff1a; 1.之后就不再單獨整理網站具體函數了&#xff0c;網站直接翻譯會…

基于微服務架構的社交學習平臺WEB系統的設計與實現

設計&#xff08;論文&#xff09;題目 基于微服務架構的社交學習平臺WEB系統的設計與實現 摘 要 社交學習平臺 web 系統要為學習者打造一個開放、互動且社交性強的在線教育環境&#xff0c;打算采用微服務架構來設計并實現一個社交學習平臺 web 系統&#xff0c;以此適應學…

生成式人工智能:重構軟件開發的范式革命與未來生態

引言 生成式人工智能&#xff08;GenAI&#xff09;正以顛覆性力量重塑軟件開發的底層邏輯。從代碼生成到業務邏輯設計&#xff0c;從數據分析到用戶交互&#xff0c;GenAI通過其強大的推理能力與場景適應性&#xff0c;將傳統開發流程的“復雜工程”轉化為“敏捷實驗”&#…

C++17原生測試編程實踐:現代特性與分支覆蓋指南

C17原生測試編程實踐&#xff1a;現代特性與分支覆蓋指南 概述 本文將深入探討如何利用C17新特性進行原生測試代碼編寫&#xff0c;實現完全分支覆蓋。我們將不依賴任何外部測試框架&#xff0c;而是使用C17標準庫構建完整的測試解決方案。 一、C17測試核心工具集 1. 斷言工…

RK3568項目(四)--uboot啟動流程之啟動模式選擇

目錄 一、引言 二、芯片初始化 ------>2.1、io_domain ------>2.2、調頻調壓 ------>2.3、控制臺初始化 三、平臺初始化 ------>3.1、設置mac地址 ------------>3.1.1、vendor分區 ------>3.2、設置serialno ------>3.3、設置下載模式 -------…

Kotlin JVM 注解詳解

前言 Kotlin 作為一門現代 JVM 語言&#xff0c;提供了出色的 Java 互操作性。為了更好地支持與 Java 代碼的交互&#xff0c;Kotlin 提供了一系列 JVM 相關注解。這些注解不僅能幫助我們控制 Kotlin 代碼編譯成 Java 字節碼的行為&#xff0c;還能讓我們的 Kotlin 代碼更好地…

Starrocks 物化視圖的實現以及在刷新期間能否讀數據

背景 本司在用Starrocks做一些業務上的分析的時候&#xff0c;用到了物化視圖&#xff0c;并且在高QPS的情況下&#xff0c;RT也沒有很大的波動&#xff0c;所以在此研究一下Starrock的實現&#xff0c;以及在刷新的時候是不是原子性的 本文基于Starrocks 3.3.5 結論 Starro…

[網頁五子棋][對戰模塊]前后端交互接口(建立連接、連接響應、落子請求/響應),客戶端開發(實現棋盤/棋子繪制)

文章目錄 約定前后端交互接口建立連接建立連接響應針對"落子"的請求和響應 客戶端開發實現棋盤/棋子繪制部分邏輯解釋 約定前后端交互接口 對戰模塊和匹配模塊使用的是兩套邏輯&#xff0c;使用不同的 websocket 的路徑進行處理&#xff0c;做到更好的耦合 建立連接 …

電工基礎【2】自鎖、互鎖、正反轉電路

04 自鎖、正反轉電路 我們講一下這個自鎖和正反轉。 自鎖電路圖示例圖 加了一個這個 KM1 自鎖。加了 KM1 的輔助觸頭&#xff0c;它怎么實現呢&#xff1f;它怎么就自鎖了呢&#xff1f;沒加它的時候為什么是點動&#xff1f;加它為什么自鎖&#xff1f; 講解一下。首先我們…

TypeScript 中感嘆號(!)兩種位置用法

這是一個非常好的問題&#xff01; 在 TypeScript 中&#xff0c;感嘆號&#xff08;!&#xff09;有兩種位置用法&#xff0c;它們含義完全不同&#xff1a; ? 一、后置感嘆號 !&#xff08;非空斷言&#xff09; process.env.ADMIN_PRIVATE_KEY! ? 作用&#xff1a; 告…

t014-項目申報管理系統 【springBoot 含源碼】

項目演示視頻 摘 要 傳統信息的管理大部分依賴于管理人員的手工登記與管理&#xff0c;然而&#xff0c;隨著近些年信息技術的迅猛發展&#xff0c;讓許多比較老套的信息管理模式進行了更新迭代&#xff0c;項目信息因為其管理內容繁雜&#xff0c;管理數量繁多導致手工進行…

【C++】STL詳解(四)---Stack和Queue

文章目錄 Stack定義方式使用方式 Queue定義方式使用方式 Stack Stack是一種容器&#xff0c;是基本的數據結構之一&#xff0c;特點是先進后出。 定義方式 方式一&#xff1a;普通定義方式 stack<int> st1;方式二&#xff1a; stack<int,vector<int>> …

解決 xmlsec.InternalError: (-1, ‘lxml xmlsec libxml2 library version mismatch‘)

解決 xmlsec.InternalError: (-1, ‘lxml & xmlsec libxml2 library version mismatch’) 錯誤信息如下&#xff1a; Traceback (most recent call last):File "/home/mobsf/Mobile-Security-Framework-MobSF/manage.py", line 18, in <module>execute_f…

SpringBoot自定義實體類字段的校驗注解

在Spring Boot項目中&#xff0c;我們經常需要對請求參數進行格式或業務規則的校驗。雖然Spring Boot提供了如NotNull、Size等基礎校驗注解&#xff0c;但在實際開發中往往無法滿足復雜的業務需求。但是在Controller層寫大量的 if 語句的判斷邏輯又實在不優雅&#xff0c;好在 …

實現單例模式的6種方法(Python)

目錄 一. 基于模塊的實現(簡單&#xff0c;易用) 二. 重新創建時報錯(不好用) 三. 只靠方法獲取實例(不好用) 四. 類裝飾器 五. 重寫__new__方法 六. 元類 七. 總結 單例模式&#xff08;Singleton Pattern&#xff09;是一種設計模式&#xff0c;其核心目標是確保一個類…

循環神經網絡(RNN)全面教程:從原理到實踐

循環神經網絡(RNN)全面教程&#xff1a;從原理到實踐 引言 循環神經網絡(Recurrent Neural Network, RNN)是處理序列數據的經典神經網絡架構&#xff0c;在自然語言處理、語音識別、時間序列預測等領域有著廣泛應用。本文將系統介紹RNN的核心概念、常見變體、實現方法以及實際…