constexpt

constexpt

constexpt是C++11引入的新的關鍵字,它用于在編譯時而非運行時計算函數或變量的值。這個特性對于提高程序效率和優化代非常有用。

編譯時常量和運行時常量

編譯時常量(Compile-time Constants)和運行時常量(Runtime Constants)是指常量在程序執行過程中被確定的時間點不同。

  • 編譯時常量

編譯時常量是指其值在程序編譯階段就已經確定并嵌入到代碼中的常量。

它們通常是直接賦值的,或者通過在編譯時可解析的表達式計算得到。

特點

  • 由于它們的值在編譯時就已確定,因此運行時無需再計算,這可以提升程序運行效率。

  • 編譯時常量通常直接存儲在程序的只讀數據段,減少了運行時內存的使用。

使用場景

  • 定義數組大小、初始化類的靜態成員、以及在程序中使用的任何固定值。
  • 在模板元編程中廣泛使用,用于在編譯時進行復雜的計算。

實現方式

  • 在 C++ 中,使用 constexpr 關鍵字來定義編譯時常量。

  • 運行時常量

定義

  • 運行時常量是指其值在程序運行時才確定的常量。
  • 它們的值可能依賴于運行時的輸入或其他只有在程序執行時才可知的數據。

特點

  • 靈活性:提供了根據運行時情況動態確定值的能力。
  • 性能開銷:由于需要在程序運行時計算,可能會引入額外的性能開銷。

使用場景

  • 當常量值依賴于用戶輸入、文件讀取、或其他運行時環境因素時。
  • 在需要根據不同的運行時條件選擇不同常量值的情況下使用。

實現方式

  • 通常通過 const 關鍵字定義,但其值賦予操作發生在程序運行時。

  • 對比

確定時間:

  • 編譯時常量:在編譯階段確定。
  • 運行時常量:在運行階段確定。

優化:

  • 編譯時常量:有助于性能優化,因為消除了運行時計算的需要。
  • 運行時常量:提供靈活性,但可能增加性能開銷。

使用關鍵字:

  • 編譯時常量:C++ 中使用 constexpr
  • 運行時常量:常用 const,但賦值發生在運行時。

特點

編譯時計算

constexpr 用于創建在編譯時就能被計算的表達式。這包括變量、函數和對象構造函數。

constexpr 用于變量時,它表明該變量的值是一個編譯時常量。這意味著變量的值必須在編譯時就已知,并且在程序的整個生命周期中保持不變。

constexpr int max_size = 100; // 編譯時常量

constexpr 用于函數時,它表示該函數在其所有參數都是常量表達式時,可以在編譯時執行。這意味著函數的返回值也必須是編譯時常量。

constexpr int factorial(int n) {return n <= 1 ? 1 : n * factorial(n - 1);
}constexpr int fact_5 = factorial(5); // 編譯時計算 5 的階乘

這里,factorial 函數被定義為 constexpr,這意味著它可以在編譯時計算階乘。因此,fact_5 的值(120)將在編譯時被計算并嵌入到編譯后的代碼中。

在 C++11 之后,constexpr 還可以用于對象的構造函數。這允許在編譯時創建和初始化對象。

class Point {
public:constexpr Point(double xVal, double yVal) : x(xVal), y(yVal) {}constexpr double getX() const { return x; }constexpr double getY() const { return y; }private:double x, y;
};constexpr Point origin(0.0, 0.0); // 編譯時創建 Point 對象

在這個例子中,Point 類的構造函數被標記為 constexpr,這使得我們可以在編譯時創建和初始化 Point 對象。

注意:constexpr 函數或構造函數在編譯時計算時必須滿足一些條件,比如不能有未定義的行為、不能有非常量表達式的分支等。如果 constexpr 表達式在編譯時不能求值,它將導致編譯錯誤。

函數限制

C++11 中的 constexpr 函數限制

在 C++11 中,constexpr 函數的使用受到相對嚴格的限制:

  1. 單一返回語句:函數體內只能包含一個 return 語句。
  2. 無循環和分支結構:不允許使用循環(如 forwhile)和復雜的分支結構(如 if-else)。
  3. 簡單的邏輯:函數通常只能執行簡單的計算,如基本的算術運算。、

如:

constexpr int add(int a, int b) {return a + b; // 只有一個 return 語句
}
C++14 中的 constexpr 函數限制放寬

C++14 放寬了這些限制,使 constexpr 函數變得更加強大和靈活:

  1. 多個返回語句:允許函數體內有多個 return 語句。
  2. 支持循環和分支:可以使用循環和條件判斷等復雜結構。
  3. 更復雜的邏輯:函數可以執行更復雜的邏輯和計算。

如:

constexpr int factorial(int n) {if (n <= 1) {return 1;} else {return n * factorial(n - 1); // 使用了遞歸}
}

類型限制

constexpr 的類型限制是 C++ 標準中的一個重要部分,確保了在編譯時可以安全且可靠地計算 constexpr 表達式。這些類型限制主要關注于字面類型(Literal Type),這是一類特定的類型,適用于編譯時的計算。以下是關于字面類型和 constexpr 的詳細解釋:

字面類型(Literal Type)

字面類型是一類特定的數據類型,它們適用于 constexpr 表達式。字面類型包括:

  1. 算術類型:包括所有的整數類型(如 intlong)和浮點類型(如 floatdouble)。

  2. 指針類型:任何類型的指針(包括指向函數的指針)。

  3. 引用類型:任何類型的引用。

  4. 某些類類型

    • 類類型必須滿足特定條件才能被視為字面類型。這些條件包括但不限于:
      • 所有成員都必須是字面類型。
      • 必須有一個 constexpr 構造函數。
      • 如果有析構函數,它必須是平凡的(trivial)。

這些類型限制確保了 constexpr 表達式在編譯時是確定的和安全的。它們可以在編譯時完全計算,沒有未定義的行為或依賴于運行時才能確定的信息。

constexpr 變量和函數的類型限制

當定義 constexpr 變量或函數時,必須確保它們的類型是字面類型:

  • 變量constexpr 變量必須是字面類型。例如,constexpr int max_size = 100; 中的 int 是字面類型。

  • 函數constexpr 函數的返回類型和所有參數類型必須是字面類型。例如,constexpr int add(int a, int b) { return a + b; } 中的返回類型 int 和參數類型 int 都是字面類型。

類類型的 constexpr 示例
class Point {
public:constexpr Point(double xVal, double yVal) : x(xVal), y(yVal) {}constexpr double getX() const { return x; }constexpr double getY() const { return y; }private:double x, y; // double 是字面類型
};constexpr Point origin(0.0, 0.0); // Point 類是字面類型

在這個例子中,Point 類是一個字面類型,因為它的所有成員都是字面類型,并且它有一個 constexpr 構造函數。

constexpt與const

const 變量的值可以在編譯時或運行時被設定。這意味著它們可以根據運行時的計算或輸入來確定其值。

const int max_users = 100; // 編譯時常量
const int current_users = getUsersCount(); // 運行時常量

用途和好處

  1. 性能提升
    • 由于在編譯時完成計算,constexpr 可以顯著減少程序運行時的時間和資源消耗。
  2. 內存使用優化
    • 編譯時計算的結果通常存儲在程序的只讀數據段,降低了運行時的內存需求。
  3. 代碼可讀性和可維護性提高
    • constexpr 提供了一種明確和直接的方式來表示編譯時常量,使得代碼意圖更清晰。
    • 減少了運行時錯誤的可能性,因為很多計算在編譯時就已確定。
  4. 更安全的代碼
    • 編譯時計算減少了運行時可能的錯誤和異常,提高了代碼的整體安全性。

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

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

相關文章

8年經驗之談 —— 如何使用自動化工具編寫測試用例?

以下為作者觀點&#xff0c;僅供參考&#xff1a; 在快速變化的軟件開發領域&#xff0c;保證應用程序的可靠性和質量至關重要。隨著應用程序復雜性和規模的不斷增加&#xff0c;僅手動測試無法滿足行業需求。 這就是測試自動化發揮作用的地方&#xff0c;它使軟件測試人員能…

leetcode做題筆記1410. HTML 實體解析器

「HTML 實體解析器」 是一種特殊的解析器&#xff0c;它將 HTML 代碼作為輸入&#xff0c;并用字符本身替換掉所有這些特殊的字符實體。 HTML 里這些特殊字符和它們對應的字符實體包括&#xff1a; 雙引號&#xff1a;字符實體為 &quot; &#xff0c;對應的字符是 "…

python appium 官網下載

找了半天吐了 https://github.com/appium/appium-desktop/releases/tag/v1.22.3-4

Hibernate批量處理數據

概念&#xff1a; 批量處理數據是指在一個事務場景中處理大量數據。 在應用程序中難以避免進行批量操作&#xff0c;Hibernate提供了以下方式進行批量處理數據&#xff1a; (1)使用HQL進行批量操作 數據庫層面 executeUpdate() (2)使用JDBC API進行批量操作 數據庫層面 …

Vue學習筆記-Object.defineproperty函數

文章目錄 前文提要Object.defineProperty作用Object.defineProperty參數使用例圖getter&#xff0c;也就是get函數setter&#xff0c;也就是set函數 前文提要 本人僅做個人學習記錄&#xff0c;如有錯誤&#xff0c;請多包涵 Object.defineProperty作用 當在js中聲明了一個變…

王道p150 20.將給定的表達式樹轉化為等價的中綴表達式(通過括號反應操作符的計算次序)

本題代碼如下 void btreetoexp(tree t, char deep) {if (t NULL)return;else if (t->lchild NULL && t->rchild NULL)printf("%c", t->data);//輸出操作數&#xff0c;不加括號else {if (deep > 1)printf("(");btreetoexp(t->l…

Rust語言入門教程(二) - 變量與作用域

變量與作用域 變量的聲明與初始化 Rust的基本語法格式如下&#xff1a; fn main(){let bunnies 2; }語句以分號結尾&#xff0c;用花括號包含語句塊。 Rust的語法其實借鑒了很多其他的語言&#xff0c;比如C語言和Python&#xff0c; 所以變量定義的格式看起來也跟很多我們…

shell 腳本的函數和數組

函數 —— 封裝的一個公式&#xff1a;sin、cos、tan —— 函數為腳本的別名 —— 函數就是一個功能模塊&#xff0c;在函數中寫執行的命令即可&#xff1b;使用函數可以避免代碼重復&#xff0c;增加可讀性&#xff0c;簡化腳本&#xff0c;使用函數可以將大的工程分割為若…

Vue中動態class方法

1.方法一&#xff1a;只需要展示一個class樣式&#xff0c;但是動態取值 <div :class"aaa"></div>data:{return () {aaa:colorRed} }.colorRed {color: red; } 2.方法二&#xff1a;表達式判斷是否展示class里面的樣式 <div :class"{colorRed…

函數與數組

一.函數 1、函數的作用 定義較為復雜的但是需要重復使用的內容&#xff0c;以便再次使用&#xff0c;可以直接調用&#xff0c;節約時間&#xff0c;提高效率。 語句塊定義成函數約等于別名&#xff0c;定義函數&#xff0c;再引用函數。 封裝的可重復利用的具有特定功能的…

python+django高校科研項目管理系統2u3mx

高校科研項目管理系統采用擬開發的高校科研項目管理系統通過測試,確保在最大負載的情況下穩定運轉,各個模塊工作正常,具有較高的可用性。系統整體界面簡潔美觀,用戶使用簡單,滿足用戶需要。在因特網發展迅猛的當今社會,高校科研項目管理系統必然會成為在數字信息化建設的一個重…

Linux 查看 CPU 信息相關命令

目錄 lscpu top htop lscpu lscpu 命令是用于顯示有關 CPU 架構的信息&#xff0c;而不是用于實時監視 CPU 負載。它提供有關 CPU 類型、核心數、線程數、架構等的詳細信息。 lscpu top 命令會顯示系統的實時狀態&#xff0c;包括 CPU 使用率、內存使用率等。按下鍵盤上的…

一文詳解Vue生命周期

Vue是一種流行的用于構建用戶界面的漸進式JavaScript框架。Vue框架在開發過程中&#xff0c;特別強調對生命周期的理解和管理。通過使用生命周期鉤子函數&#xff0c;開發者能夠精確地控制Vue實例的創建、掛載、更新以及銷毀過程。本文將對Vue的生命周期進行詳細的介紹&#xf…

YOLOv8訓練自己的目標檢測數據集

YOLOv8訓練自己的目標檢測數據集 目錄標題 源碼下載環境配置安裝包訓練自己的數據集數據集文件格式數據集文件配置超參數文件配置訓練數據集命令行訓練腳本.py文件訓練 進行detect顯示detect的效果 源碼下載 YOLOv8官方的GitHub代碼&#xff0c;同時上面也有基礎環境的配置要…

IntelliJ IDEA 16創建Web項目

首先要理解一個概念&#xff1a;在IntelliJ IDEA中“new Project”相當于eclipse中的工作空間&#xff08;Workspace&#xff09;&#xff0c;而“new Module”相當于eclipse中的工程&#xff08;Project&#xff09;。以下均采用Intellij的說法&#xff0c;請自行對照轉換理解…

Maven倉庫清除remote.repositories、lastUpdated、sha1腳本

Maven倉庫清除remote.repositories、lastUpdated、sha1腳本 1. 腳本功能 清除本地maven倉庫的_remote.repositories、sha1、lastUpdated的文件 2. 腳本內容 set REPOSITORY_PATH%cd% rem 搜索中... for /f "delims" %%i in (dir /b /s "%REPOSITORY_PATH%\*…

Java 關鍵字:synchronized詳解

synchronized詳解 基本使用源碼解析常見面試題好書推薦 基本使用 Java中的synchronized關鍵字用于在多線程環境下確保數據同步。它可以用來修飾方法和代碼塊 當一個線程訪問一個對象的synchronized方法或代碼塊時&#xff0c;其他線程將無法訪問該對象的其他synchronized方法或…

【愚公系列】2023年11月 Java教學課程 188-SpringCloud(Feign遠程調用)

&#x1f3c6; 作者簡介&#xff0c;愚公搬代碼 &#x1f3c6;《頭銜》&#xff1a;華為云特約編輯&#xff0c;華為云云享專家&#xff0c;華為開發者專家&#xff0c;華為產品云測專家&#xff0c;CSDN博客專家&#xff0c;阿里云專家博主&#xff0c;阿里云簽約作者&#xf…

如何通過寶塔面板搭建一個本地MySQL數據庫服務并實現遠程訪問

寶塔安裝MySQL數據庫&#xff0c;并內網穿透實現公網遠程訪問 文章目錄 寶塔安裝MySQL數據庫&#xff0c;并內網穿透實現公網遠程訪問前言1.Mysql服務安裝2.創建數據庫3.安裝cpolar3.2 創建HTTP隧道 4.遠程連接5.固定TCP地址5.1 保留一個固定的公網TCP端口地址5.2 配置固定公網…

浙江師范黃昌勤老師關于情感分析的講座

回放&#xff1a;https://share.weiyun.com/Wvaw4OoY 收獲很大&#xff1a; 寫幾點&#xff0c; 1&#xff1a;小二聚焦 精細更有用 2&#xff1a;高產的秘訣就是 專注一個領域&#xff0c;不斷延展。 3&#xff1a;好的文章技術不是本質&#xff0c;本質還是解決了什么教育問…