<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      constexpr

      constexpr(const expression常量表達式)

      只有像1,'a',2.5f之類的才是真正的常量。儲存在內存中的數據都應當叫做“變量”。我們既希望定義一個安全的值,又不希望這個數據成為「變量」來占用空間。關鍵字 constexpr 是在 C++11 中引入的,并在 C++14 中進行了改進。 它表示「常量表達式」。 與 const 一樣,它可以應用于變量:當任何代碼嘗試修改值時,都會引發編譯器錯誤。 與 const 不同,constexpr 還可以應用于函數和類構造函數。 constexpr 指示該值或返回值是常量,并且盡可能在編譯時計算。

      constexpr變量

      constconstexpr 變量之間的主要區別是, const 變量的初始化可能推遲到運行時。 constexpr 變量必須在 編譯期初始化 。所有的 constexpr 變量都是 const。 。

      • 如果一個變量具有文本類型且已經初始化,則可以用 constexpr 聲明,如果初始化是由構造函數執行的,那么必須將構造函數聲明為 constexpr
      • 當滿足以下兩個條件時,可以將引用聲明為 constexpr:
        • 引用的對象由常量表達式初始化
        • 在初始化期間所調用的任何隱式轉換也均是常數表達式。
      • constexpr 變量或函數的所有聲明都必須具有 constexpr 說明符。
      struct Test {
          Test() : a(10) {}
          const int a; // ok
      };
      
      constexpr float x = 42.0;
      constexpr float y{108};
      constexpr float z = exp(5, 3);
      constexpr int i; // Error! Not initialized
      int j = 0;
      constexpr int k = j + 1; //Error! j not a constant expression
      

      變量:

      constexpr int x = 42; //ok,文本類型+常量表達式初始化
      constexpr float y = sqrt(9.0); // ok,如果sqrt是constexpr函數
      class Point {
      public:
          constexpr Point(int a, int b) : x(a), y(b) {}  // constexpr構造函數
          int x, y;
      };
      constexpr Point p(1, 2); // 合法:構造函數是constexpr
      

      引用:

      constexpr int a = 10;
      constexpr const int& ref = a;  // 合法:a是常量表達式
      constexpr double b = 3.14;
      constexpr int c = static_cast<int>(b);  // 合法:顯式轉換是編譯期常量
      

      constexpr函數

      constexpr 函數主要適用于編譯期返回 constexpr 變量。 使用在需要編譯時的返回值來初始化 constexpr 變量時,或者用于提供非類型模板的自變量。 如果參數是 constexpr 值時, constexpr 函數會生成編譯時常量。 如果是不同的值時,或者編譯期時不需要其去調用執行這個函數,它將與普通函數一樣,在運行時生成一個值。 (此行為使你無需編寫同一函數的 constexpr 和非 constexpr 版本。)
      constexpr 函數或構造函數是隱式 inline。
      以下規則適用于「constexpr函數」:

      • constexpr 函數必須只接受并返回文本類型,即編譯期可確定的值。
      • constexpr 函數可以是遞歸的。
      • 在 C++20 之前, constexpr 函數不能是虛,并且當類具有任何虛擬基類時,不能將構造函數定義為 constexpr 。 在 C++20 及更高版本中, constexpr 函數可以是虛函數。
      • 主體可以定義為 = default= delete
      • C++11僅支持 return ,C++14之后允許局部變量、循環、條件語句,但不能包含 goto 語句或 try 塊、動態內存分配( new 、 delete )以及修改全局變量。
      • constexpr 模板的顯式特化可聲明為 constexpr
        • 即使原模板未標記 constexpr ,其顯式特化版本可單獨聲明為 constexpr ,以滿足特定類型的編譯期計算需求。
      template <typename T>
      T add(T a, T b) { return a + b; }  // 非constexpr模板
      
      template <>
      constexpr int add<int>(int a, int b) { return a + b; }  // 顯式特化為constexpr
      
      • constexpr 模板的顯式特化不必是 constexpr
        • 若原模板為 constexpr ,其顯式特化可選擇性省略 constexpr ,退化為運行時函數。
        • 用途:針對某些類型需運行時處理時(如涉及I/O或動態內存),保留靈活性。
      template <typename T>
      constexpr T square(T x) { return x * x; }  // constexpr模板
      
      template <>
      double square<double>(double x) { return x * x; }  // 顯式特化非constexpr
      

      constexpr 表達式也可能是變成變量

      雖然 constexpr 已經是常量表達式了,但是用 constexpr 修飾變量的時候,它仍然是“定義變量”的語法,因此C++希望它能夠兼容只讀變量的情況。
      當且僅當一種情況下, constexpr 定義的變量會真的成為變量,那就是這個變量被取址的時候:

      void Demo() {
          constexpr int a = 5;
          const int *p = &a; // 會讓a退化為const int類型
      }
      

      道理也很簡單,因為只有變量才能取址。上面例子中,由于對 a 進行了取地址操作,因此, a 不得不真正成為一個變量,也就是變為 const int 類型。
      那另一個問題就出現了,如果說,我對一個常量表達式既取了地址,又用到編譯期語法中了怎么辦?

      template <int N>
      struct Test {};
      
      void Demo() {
          constexpr int a = 5;
          Test<a> t; // 用做常量
          const int *p = &a; // 用做變量
      }
      

      沒關系,編譯器會讓它在編譯期視為常量去給那些編譯期語法(比如模板實例化)使用,之后,再把它用作變量寫到內存中。

      換句話說,在編譯期,這里的a相當于一個宏,所有的編譯期語法會用5替換a,Test<a> 就變成了 Test<5>。之后,又會讓 a 成為一個只讀變量寫到內存中,也就變成了 const int a = 5; 那么 const int *p = &a; 自然就是合法的了。

      if constexpr

      C++17引入的編譯時條件判斷工具,在編譯時進行判斷,編譯條件必須是常量表達式,針對 false 的情況,不進行編譯。

      #include <iostream>
      #include <type_traits>
      
      template<typename T>
      void handleValue(const T& value) {
          if constexpr (std::is_integral_v<T>) {
              // 此分支僅在 T 為整型時編譯
              std::cout << value << " 是整型,進行整型處理。" << std::endl;
          } else if constexpr (std::is_floating_point_v<T>) {
              // 此分支僅在 T 為浮點型時編譯
              std::cout << value << " 是浮點型,進行浮點型處理。" << std::endl;
          } else {
              // 此分支用于其他類型
              std::cout << value << " 是其他類型。" << std::endl;
          }
      }
      
      int main() {
          handleValue(42);    // 輸出:42 是整型,進行整型處理。
          handleValue(3.14);  // 輸出:3.14 是浮點型,進行浮點型處理。
          handleValue("Hello"); // 輸出:Hello 是其他類型。
          return 0;
      }
      
      

      constexpr lambda

      constexpr lambda 是 C++17 引入的特性,允許 lambda 表達式在編譯時進行求值,從而將編譯時計算的能力與 lambda 的簡潔語法相結合。
      一個 constexpr lambda 可以通過在參數列表后顯式添加 constexpr 關鍵字來聲明:

      auto square = [](int n) constexpr { return n * n; };
      

      如果 lambda 體的操作都滿足 constexpr 函數的要求(例如,只包含確定性操作,不進行 I/O 或調用非 constexpr 函數),那么它也可以被隱式地視為 constexpr ,無需顯式聲明

      // 這是一個隱式的 constexpr lambda
      auto add = [](int a, int b) { return a + b; };
      constexpr int result = add(10, 20); // 編譯時計算
      
      posted @ 2025-11-05 12:39  神洛桃玖  閱讀(0)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 人人妻人人狠人人爽| 国产成人啪精品午夜网站| 亚洲精品一二三中文字幕| 奈曼旗| 日韩淫片毛片视频免费看| 少妇被无套内谢免费看| 日本高清一区免费中文视频| 中文字幕日韩精品东京热| 亚洲高清国产拍精品熟女| 欧美日韩中文字幕久久伊人| 天天躁夜夜躁狠狠综合| 亚洲一区二区三区自拍天堂| 男女性高爱潮免费网站| 人妻少妇偷人无码视频| 亚洲av色在线播放一区| 玖玖在线精品免费视频| 亚洲 中文 欧美 日韩 在线| 温泉县| 四虎在线成人免费观看| 国内精品视频区在线2021| 国产乱人激情H在线观看| 天天燥日日燥| 亚洲国产成人av毛片大全 | 亚洲国产欧美在线人成AAAA| 精品一区精品二区制服| 济阳县| 中文 在线 日韩 亚洲 欧美| 少妇久久久被弄到高潮| 中文字幕乱码人妻二区三区 | 少妇爽到呻吟的视频| 亚洲男人天堂一级黄色片| 无码人妻精品一区二区三区下载| 久久国产免费观看精品3| 18禁免费无码无遮挡网站| 91福利国产成人精品导航| 精品久久久久久无码人妻蜜桃| 性色av 一区二区三区| 日本精品不卡一二三区| 久久亚洲精品中文字幕馆| 天天干天天色综合网| 国产精品免费AⅤ片在线观看 |