10、const和constexpr區別

来源:https://www.cnblogs.com/dbai/archive/2023/03/13/17212678.html
-Advertisement-
Play Games

首先理解常亮表達式。常量表達式是指值不會改變,並且在編譯過程就能計算得到結果。 const修飾的對象無法修改,constexpr對象在編譯期間就確定且無法修改。 constexpr變數,編譯器在編譯階段驗證變數是否為一個常量表達式。 constexpr側重變數初值編譯階段確定,且無法修改。如果認定變 ...


首先理解常亮表達式。常量表達式是指值不會改變,並且在編譯過程就能計算得到結果。

  1. const修飾的對象無法修改,constexpr對象在編譯期間就確定且無法修改。
  2. constexpr變數,編譯器在編譯階段驗證變數是否為一個常量表達式。
  3. constexpr側重變數初值編譯階段確定,且無法修改。如果認定變數是一個常量表達式,就把它聲明稱constexpr類型。
  4. 兩者都必須初始化。

1、const

const int i = get_size(); // 運行時初始化
const iny j = 42; // 編譯時初始化

1.1 const對象僅在文件內有效

如果要多個文件共用一個const對象,需要加關鍵字extern

extern const int i =10;

1.2 頂層和底層const

頂層const指針自身無法修改
底層const指針可以修改

int i = 10;
int *const p1 = &i; // 頂層const:不能修改p1的值
const int *p2 = &i; // 底層const:不能修改p2指針指向
const int *const p3 = &i; // 底層+頂層const
const int &r = i; // 底層const:不能通過r修改i值

1.3 const代替#define

程式編譯過程氛圍:預處理、編譯和鏈接。#define在預處理階段接回展開,在編譯階段如果遇到錯誤,報錯信息不明朗。

// 不推薦
#define e 2.7

// 推薦
const double e = 2.7;

1.4 修飾變數

const int sz = get_size(); // 雖然sz無法改變,但get_size() 編譯階段無法確定值,也就是說sz不是常量表達式

1.5 修飾指針

int i = 1;
int *const p1 = &i; // 頂層const
const int *p2 = &i; // 底層const

1.6 修飾函數

int size() const { curSize = 1; return curSize; }; // 錯誤:const函數不能修改任何類的數據成員
int size() const { setSize(); return curSize; } // 錯誤:const函數只能調用const函數
const int size() { return curSize; }  // 函數返回值為const類型

2、constexpr

C++11引入了常量表達式constexpr的概念,指的是值不會改變並且在編譯期間就能得到計算結果的表達式。

const int i = 1;          // 常量表達式
const int j = i + 1;       // 常量表達式
const int k = size();      // 當size()是一個constexpr函數時才是常量表達式,

2.1 修飾變數

constexpr int i = 20; // 字面量20是常量表達式
constexpr int j = i + 1; // mf + 1是常量表達式
constexpr int k = size(); // 只有當size是constexpr函數時,才是正確的

2.2 修飾指針

constexpr修飾指針,僅對指針有效,與指針所指對象無關

// j的定義必須放在函數體外
int j = 30;

// 函數體內
constexpr int *p1 = &j; // 等價於 int constexpr *p1 = &j;
*p1 = 40; // 正確
p1 = nullptr; // 錯誤,constexpr指針無法修改

2.3 修飾函數

constexpr無法修飾成員函數,只能作為函數返回值類型,表明該函數返回的是一個編譯期可確定的常量;constexpr 被隱式隱式指定為內聯函數,只能在類的聲明中定義(.h文件)

// 函數返回值為constexpr類型
constexpr int getMaxSize() { return INT_MAX; } // 正確示例:返回常量值
// 錯誤示例:vec.size()運行時確定,不能在編譯期決定
constexpr int getMaxSize() 
{
	std::vector<int> vec;
	vec.push_back(1);
	vec.push_back(2);
	return vec.size();
}
// 正確:雖然看起來返回的是變數,但編譯器可確定
constexpr int getMaxSize(int a, int b) 
{
  return a + b;
}

部分內容來源:(明明1109)原文鏈接:https://www.cnblogs.com/fortunely/p/14550145.html


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 這篇文章主要描述應用程式之間的通信協議,包括進行數據“斷句”的兩種不同方法,以及在應用協議層面實現高性能的雙工通信。 ...
  • 簡介 建造者模式(Builder Pattern),也叫生成器模式,屬於創建型模式。它使用多個簡單的對象一步一步構建成一個複雜的對象。它允許你使用相同的創建代碼生成不同類型和形式的對象。 當你希望使用代碼創建不同形式的產品 (例如各種商品和訂單) 時, 一些基本部件不會變,而其組合經常變化的時候,就 ...
  • 軟體設計開發某種意義上是“取”與“舍”的藝術。 關於性能方面,就像建築設計成抗震9度需要額外的成本一樣,高性能軟體系統也意味著更高的實現成本,有時候與其他質量屬性甚至會衝突,比如安全性、可擴展性、可觀測性等等。 大部分時候我們需要的是:在業務遇到瓶頸之前,利用常見的技術手段將系統優化到預期水平。 ...
  • Spring:現代Java開發的必備框架 Spring是一個輕量級的Java框架,它提供了各種企業級應用程式開發的工具和技術。Spring框架的核心是IoC容器和AOP框架。IoC容器使得Java應用程式的組件化變得更加容易,AOP框架使得Java應用程式的切麵編程變得更加容易。Spring框架還提 ...
  • 1、當使用生成介面 生成全局模型時, 生成的validate文件的namespace錯誤 應為 namespace app\common\validate;實際為 namespace app\api\validate;解決方法:1、找到 application/admin/library/buiap ...
  • 容器功能 1.Spring註入組件的註解 Spring中的傳統註解@Component、@Controller、@Service、@Repository,在SpringBoot中仍然有效。 2.@Configuration @Configuration是 Spring 3.0 添加的一個註解,用來代 ...
  • 我是3y,一年CRUD經驗用十年的markdown程式員👨🏻‍💻常年被譽為職業八股文選手 開源項目消息推送平臺austin倉庫地址: 消息推送平臺🔥推送下發【郵件】【簡訊】【微信服務號】【微信小程式】【企業微信】【釘釘】等消息類型。 https://gitee.com/zhongfuchen ...
  • 搞懂無鎖編程的重要一步是完全理解記憶體順序! 本教程由作者和ChatGPT通力合作完成。 都有哪幾種? c++的記憶體模型共有6種 memory_order_relaxed memory_order_consume memory_order_acquire memory_order_release me ...
一周排行
    -Advertisement-
    Play Games
  • .Net8.0 Blazor Hybird 桌面端 (WPF/Winform) 實測可以完整運行在 win7sp1/win10/win11. 如果用其他工具打包,還可以運行在mac/linux下, 傳送門BlazorHybrid 發佈為無依賴包方式 安裝 WebView2Runtime 1.57 M ...
  • 目錄前言PostgreSql安裝測試額外Nuget安裝Person.cs模擬運行Navicate連postgresql解決方案Garnet為什麼要選擇Garnet而不是RedisRedis不再開源Windows版的Redis是由微軟維護的Windows Redis版本老舊,後續可能不再更新Garne ...
  • C#TMS系統代碼-聯表報表學習 領導被裁了之後很快就有人上任了,幾乎是無縫銜接,很難讓我不想到這早就決定好了。我的職責沒有任何變化。感受下來這個系統封裝程度很高,我只要會調用方法就行。這個系統交付之後不會有太多問題,更多應該是做小需求,有大的開發任務應該也是第二期的事,嗯?怎麼感覺我變成運維了?而 ...
  • 我在隨筆《EAV模型(實體-屬性-值)的設計和低代碼的處理方案(1)》中介紹了一些基本的EAV模型設計知識和基於Winform場景下低代碼(或者說無代碼)的一些實現思路,在本篇隨筆中,我們來分析一下這種針對通用業務,且只需定義就能構建業務模塊存儲和界面的解決方案,其中的數據查詢處理的操作。 ...
  • 對某個遠程伺服器啟用和設置NTP服務(Windows系統) 打開註冊表 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time\TimeProviders\NtpServer 將 Enabled 的值設置為 1,這將啟用NTP伺服器功 ...
  • title: Django信號與擴展:深入理解與實踐 date: 2024/5/15 22:40:52 updated: 2024/5/15 22:40:52 categories: 後端開發 tags: Django 信號 松耦合 觀察者 擴展 安全 性能 第一部分:Django信號基礎 Djan ...
  • 使用xadmin2遇到的問題&解決 環境配置: 使用的模塊版本: 關聯的包 Django 3.2.15 mysqlclient 2.2.4 xadmin 2.0.1 django-crispy-forms >= 1.6.0 django-import-export >= 0.5.1 django-r ...
  • 今天我打算整點兒不一樣的內容,通過之前學習的TransformerMap和LazyMap鏈,想搞點不一樣的,所以我關註了另外一條鏈DefaultedMap鏈,主要調用鏈為: 調用鏈詳細描述: ObjectInputStream.readObject() DefaultedMap.readObject ...
  • 後端應用級開發者該如何擁抱 AI GC?就是在這樣的一個大的浪潮下,我們的傳統的應用級開發者。我們該如何選擇職業或者是如何去快速轉型,跟上這樣的一個行業的一個浪潮? 0 AI金字塔模型 越往上它的整個難度就是職業機會也好,或者說是整個的這個運作也好,它的難度會越大,然後越往下機會就會越多,所以這是一 ...
  • @Autowired是Spring框架提供的註解,@Resource是Java EE 5規範提供的註解。 @Autowired預設按照類型自動裝配,而@Resource預設按照名稱自動裝配。 @Autowired支持@Qualifier註解來指定裝配哪一個具有相同類型的bean,而@Resourc... ...