最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

使用c++11 constexpr時(shí)遇到的坑詳解

 更新時(shí)間:2021年05月16日 10:22:50   作者:apocelipes  
c++11 constexpr將變量聲明為constexpr類型以便由編譯器來驗(yàn)證變量是否是一個(gè)常量表達(dá)式,這篇文章主要給大家介紹了關(guān)于使用c++11 constexpr時(shí)遇到的坑,需要的朋友可以參考下

最近在使用constexpr的時(shí)候無意中踩了個(gè)小坑。

下面給個(gè)小示例:

#include <iostream>

constexpr int n = 10;
constexpr char *msg = "Hello, world!";

int main()
{
    for (auto i = 0; i < n; ++i) {
        std::cout << msg << std::endl;
    }
}

constexpr應(yīng)該是大家很熟悉的東西了,也是最常用的c++11新特性之一。和宏相比除了更強(qiáng)的類型安全之外,constexpr還帶來了編譯期計(jì)算。

上面的代碼相當(dāng)簡單,我們循環(huán)輸出“Hello, world!”這個(gè)字符串10次。

這么簡單的代碼還有討論的必要嗎?一開始我也是這么想的,然而當(dāng)我們編譯運(yùn)行的時(shí)候卻會(huì)得到下面這樣的警告:

$ g++ --version
                      
g++ (GCC) 10.2.0
Copyright (C) 2020 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.


$ g++ -std=c++17 -Wall -Wextra test.cpp

test.cpp:4:23: 警告: ISO C++ forbids converting a string constant to ‘char*' [-Wwrite-strings]
    4 | constexpr char *msg = "Hello, world!";
      |                       ^~~~~~~~~~~~~~~

這段信息的意思是c++不允許把字符串字面量賦值給char*。

然而對于constexpr,文檔中是這么寫的:

A constexpr specifier used in an object declaration implies const.

這里的object你可以理解為變量,意思是constexpr修飾的變量都會(huì)隱式添加一個(gè)const限定符。

也就是說:

// T 是任意類型
constexpr T a = xxx;
// 不考慮其他因素,在類型上等價(jià)于:
T const a = xxx;

我們這里的T實(shí)際上可以填任意類型,包括指針。這不是說明我們的指針變量有const嗎?

眼尖的讀者大概已經(jīng)知道答案了:constexpr添加的是頂層const。

所以我們的代碼實(shí)際上是這樣的:

// 原本的代碼
constexpr char *msg = "Hello, world!";
// 實(shí)際上的效果
char * const msg = "Hello, world!";

下面一行的msg實(shí)際上是一個(gè)指向char的指針常量,而我們可以通過它任意修改被指向的字符串(當(dāng)然這是未定義行為)。指針常量意味著我們不能把這個(gè)指針重新指向其他的對象,這個(gè)const作用在指針本身上,因此叫做頂層const。

而字符串常量的類型是const char[N],在表達(dá)式里退化為const char *,這表示一個(gè)指向常量字符串的指針,這里的const的底層的,因?yàn)樗饔糜诒恢赶虻膶ο蠖皇俏覀兊闹羔樧陨怼?/p>

對于頂層const,賦值的時(shí)候是可以被去除的,而底層const則不行,這就是為什么編譯器會(huì)彈出警告的原因了。

正確的做法也很簡單,牢記constexpr不是const的等價(jià)替代品,它只會(huì)添加頂層const,不會(huì)添加底層const。

所以constexpr的字符串常量應(yīng)該這樣寫:

constexpr const char *p = "Hello, world!";

或者你的編譯環(huán)境支持c++17,我更推薦你這樣寫:

#include <string_view>

constexpr std::string_view msg = "Hello, world!";

使用string_view之后就不會(huì)出現(xiàn)上面的頂層/底層const的坑了。所以在現(xiàn)代c++里能不用裸指針就盡量不要用。

參考

https://stackoverflow.com/questions/54258241/warning-iso-c-forbids-converting-a-string-constant-to-char-for-a-static-c

總結(jié)

到此這篇關(guān)于使用c++11 constexpr時(shí)遇到坑的文章就介紹到這了,更多相關(guān)c++11 constexpr坑內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • VS2019安裝cbd調(diào)試器的實(shí)現(xiàn)步驟

    VS2019安裝cbd調(diào)試器的實(shí)現(xiàn)步驟

    本文主要介紹了VS2019安裝cbd調(diào)試器的實(shí)現(xiàn)步驟,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-12-12
  • C++中fstream,ifstream及ofstream用法淺析

    C++中fstream,ifstream及ofstream用法淺析

    這篇文章主要介紹了C++中fstream,ifstream及ofstream用法,適合C++初學(xué)者學(xué)習(xí)文件流的操作,需要的朋友可以參考下
    2014-08-08
  • C語言深入講解宏的定義與使用方法

    C語言深入講解宏的定義與使用方法

    在 C 語言中,可以采用命令 #define 來定義宏。該命令允許把一個(gè)名稱指定成任何所需的文本,例如一個(gè)常量值或者一條語句。在定義了宏之后,無論宏名稱出現(xiàn)在源代碼的何處,預(yù)處理器都會(huì)把它用定義時(shí)指定的文本替換掉
    2022-04-04
  • C++讀入

    C++讀入"N,X,Y,Z"格式文本文件到Eigen3 Matrix

    這篇文章主要介紹了C++讀入"N,X,Y,Z"格式文本文件到Eigen3 Matrix,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-04-04
  • C++基于對話框的程序的框架實(shí)例

    C++基于對話框的程序的框架實(shí)例

    這篇文章主要介紹了C++基于對話框的程序的框架,以實(shí)例形式講述了C++對話框程序框架,有助于深入理解基于C++的Windows程序設(shè)計(jì),需要的朋友可以參考下
    2014-10-10
  • C語言基礎(chǔ)函數(shù)用法示例詳細(xì)解析

    C語言基礎(chǔ)函數(shù)用法示例詳細(xì)解析

    最接地氣的C函數(shù)基礎(chǔ)介紹,此處對于函數(shù)的相關(guān)知識點(diǎn)做一些簡要的介紹,作者實(shí)屬初學(xué),寫博客也是作者學(xué)習(xí)的一個(gè)過程,難免文章中有內(nèi)容理解不到位或者有不當(dāng)之處,還請朋友們不吝指正
    2021-11-11
  • C++六大默認(rèn)成員函數(shù)的實(shí)現(xiàn)

    C++六大默認(rèn)成員函數(shù)的實(shí)現(xiàn)

    C++中的六大默認(rèn)成員函數(shù)包括默認(rèn)構(gòu)造函數(shù)、默認(rèn)析構(gòu)函數(shù)、默認(rèn)拷貝構(gòu)造函數(shù)、默認(rèn)拷貝賦值運(yùn)算符、移動(dòng)構(gòu)造函數(shù)和移動(dòng)賦值運(yùn)算符,本文就來介紹一下這些函數(shù)的使用,感興趣的可以了解一下
    2025-02-02
  • C++中的對象數(shù)組詳細(xì)解析

    C++中的對象數(shù)組詳細(xì)解析

    在建立數(shù)組時(shí),同樣要調(diào)用構(gòu)造函數(shù)。如果有50個(gè)元素,就需要調(diào)用50次構(gòu)造函數(shù)。在需要的時(shí)候,可以在定義數(shù)組時(shí)提供實(shí)參以實(shí)現(xiàn)初始化
    2013-10-10
  • C語言實(shí)現(xiàn)簡單的貪吃蛇游戲的示例代碼

    C語言實(shí)現(xiàn)簡單的貪吃蛇游戲的示例代碼

    這篇文章主要為大家詳細(xì)介紹了C語言如何實(shí)現(xiàn)經(jīng)典貪吃蛇游戲,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)C語言有一定的幫助,感興趣的小伙伴可以跟隨小編一起了解一下
    2023-01-01
  • C語言鄰接表建立圖詳解

    C語言鄰接表建立圖詳解

    這篇文章主要介紹了C語言鄰接表建立圖,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08

最新評論

潮安县| 大石桥市| 蓝山县| 新蔡县| 二连浩特市| 新昌县| 申扎县| 兴业县| 潮安县| 泰和县| 茶陵县| 聂拉木县| 祁阳县| 磴口县| 阳朔县| 永平县| 凉城县| 奉化市| 曲水县| 新巴尔虎左旗| 桑植县| 怀仁县| 会泽县| 萍乡市| 会同县| 海晏县| 什邡市| 句容市| 白沙| 白银市| 隆林| 贞丰县| 利辛县| 和田市| 巴东县| 黄骅市| 台前县| 丰都县| 衡水市| 赣州市| 关岭|