詳解C++17中nodiscard標(biāo)記符的使用
前言
在C++ 17中引入了一個標(biāo)記符nodiscard,用于聲明一個 “非棄值(no-discard)表達(dá)式”。那么在開始之前,我們需要了解一下什么是棄值表達(dá)式。
棄值表達(dá)式
棄值表達(dá)式,就是放棄獲取返回值的表達(dá)式。首先棄值表達(dá)式的返回值是非void類型的。一般,我們使用的棄值表達(dá)式,其返回值只是起次要的作用,而其本身的作用占主要。比如++i;就是一個棄值表達(dá)式,它的主要作用就是累加,但同時我們也可以選擇獲取其累加的返回值,只不過這是次要的。
再比如,C標(biāo)準(zhǔn)庫的文件寫入函數(shù),其聲明如下:
int __cdecl fputs(const char * __restrict__ _Str,FILE * __restrict__ _File);
它有一個int類型的返回值,用于獲取寫入狀態(tài),它的主要作用是寫入文件,我可以選擇不獲取狀態(tài),也可以選擇獲取狀態(tài):
fputs("Hello World",pFile); int result = fputs("Hello World",pFile);
nodiscard標(biāo)記符
那么我如果想向用戶建議獲取返回值,這時候,我就可以使用nodiscard標(biāo)記符。它一般用于標(biāo)記函數(shù)的返回值或者某個類。聲明語法為:
/* @since C++17 */ [[nodiscard]] return_type function(); /* @since C++20 */ [[nodiscard("message")]] return_type function(); /* Standard lib defination */ /* #if __cplusplus >= 201703L # define _GLIBCXX_NODISCARD [[__nodiscard__]] #else # define _GLIBCXX_NODISCARD #endif */ _GLIBCXX_NODISCARD return_type function();
如果一個被nodiscard標(biāo)記了的表達(dá)式,如果我們在使用時棄值了,而且沒有使用static_cast<void>將其轉(zhuǎn)化為void時,編譯器會拋出warning來提醒用戶獲取返回值。
函數(shù)非棄值聲明
[[nodiscard]] int func1(){ return 1; } [[nodiscard("nodiscared function")]] int func2(){ return 1; } int main(){ func1(); //warning C++17 func2(); //warning c++20 int a = func1(); //no warning static_cast<void>(func1()); //no warning }
結(jié)果如下:
類/枚舉類/結(jié)構(gòu) 非棄值聲明
class [[nodiscard]] A{}; enum class [[nodiscard]] B{X,Y}; struct [[nodiscard]] C{}; A createA(){ return A(); } B createB(){ return B::X; } C createC(){ return C(); } int main(){ createA(); createB(); createC(); }
輸出如下:
6.cpp: In function 'int main()':
6.cpp:22:12: warning: ignoring returned value of type 'A', declared with attribute 'nodiscard' [-Wunused-result]
22 | createA();
| ~~~~~~~^~
6.cpp:10:3: note: in call to 'A createA()', declared here
10 | A createA(){
| ^~~~~~~
6.cpp:6:21: note: 'A' declared here
6 | class [[nodiscard]] A{};
| ^
6.cpp:23:12: warning: ignoring returned value of type 'B', declared with attribute 'nodiscard' [-Wunused-result]
23 | createB();
| ~~~~~~~^~
6.cpp:14:3: note: in call to 'B createB()', declared here
14 | B createB(){
| ^~~~~~~
6.cpp:7:26: note: 'B' declared here
7 | enum class [[nodiscard]] B{X,Y};
| ^
6.cpp:24:12: warning: ignoring returned value of type 'C', declared with attribute 'nodiscard' [-Wunused-result]
24 | createC();
| ~~~~~~~^~
6.cpp:18:3: note: in call to 'C createC()', declared here
18 | C createC(){
| ^~~~~~~
6.cpp:8:22: note: 'C' declared here
8 | struct [[nodiscard]] C{};
| ^
返回類引用與類指針
當(dāng)返回值為引用或者指針的 類/枚舉類/結(jié)構(gòu)(函數(shù)不行) 時,nodiscard 就無效了:
class [[nodiscard]] A{}; A& createAref(){ A* a = new A(); return *a; } A* createAptr(){ A* a = new A(); return a; } int main(){ createAref(); //no warning createAptr(); //no warning }
到此這篇關(guān)于詳解C++17中nodiscard標(biāo)記符的使用的文章就介紹到這了,更多相關(guān)C++17 nodiscard標(biāo)記符內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++使用宏函數(shù)實(shí)現(xiàn)單例模板詳解
在我們?nèi)粘i_發(fā)中,無可避免需要使用單例模式進(jìn)行設(shè)計(jì)類對象。這篇文章主要介紹了如何使用宏函數(shù)實(shí)現(xiàn)單例模板,感興趣的小伙伴可以了解一下2023-02-02C++ 使用CRC32檢測內(nèi)存映像完整性的實(shí)現(xiàn)步驟
當(dāng)我們使用動態(tài)補(bǔ)丁的時候,那么內(nèi)存中同樣不存在校驗(yàn)效果,也就無法抵御對方動態(tài)修改機(jī)器碼了,為了防止解密者直接對內(nèi)存打補(bǔ)丁,我們需要在硬盤校驗(yàn)的基礎(chǔ)上,增加內(nèi)存校驗(yàn),防止動態(tài)補(bǔ)丁的運(yùn)用。2021-06-06C語言詳細(xì)分析常見字符串函數(shù)與模擬實(shí)現(xiàn)
字符串函數(shù)(String?processing?function)也叫字符串處理函數(shù),指的是編程語言中用來進(jìn)行字符串處理的函數(shù),如C,pascal,Visual以及LotusScript中進(jìn)行字符串拷貝,計(jì)算長度,字符查找等的函數(shù)2022-03-03