詳解C++17中nodiscard標(biāo)記符的使用
前言
在C++ 17中引入了一個(gè)標(biāo)記符nodiscard,用于聲明一個(gè) “非棄值(no-discard)表達(dá)式”。那么在開始之前,我們需要了解一下什么是棄值表達(dá)式。
棄值表達(dá)式
棄值表達(dá)式,就是放棄獲取返回值的表達(dá)式。首先棄值表達(dá)式的返回值是非void類型的。一般,我們使用的棄值表達(dá)式,其返回值只是起次要的作用,而其本身的作用占主要。比如++i;就是一個(gè)棄值表達(dá)式,它的主要作用就是累加,但同時(shí)我們也可以選擇獲取其累加的返回值,只不過這是次要的。
再比如,C標(biāo)準(zhǔn)庫的文件寫入函數(shù),其聲明如下:
int __cdecl fputs(const char * __restrict__ _Str,FILE * __restrict__ _File);
它有一個(gè)int類型的返回值,用于獲取寫入狀態(tài),它的主要作用是寫入文件,我可以選擇不獲取狀態(tài),也可以選擇獲取狀態(tài):
fputs("Hello World",pFile); int result = fputs("Hello World",pFile);
nodiscard標(biāo)記符
那么我如果想向用戶建議獲取返回值,這時(shí)候,我就可以使用nodiscard標(biāo)記符。它一般用于標(biāo)記函數(shù)的返回值或者某個(gè)類。聲明語法為:
/* @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();
如果一個(gè)被nodiscard標(biāo)記了的表達(dá)式,如果我們?cè)谑褂脮r(shí)棄值了,而且沒有使用static_cast<void>將其轉(zhuǎn)化為void時(shí),編譯器會(huì)拋出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ù)不行) 時(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)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++使用宏函數(shù)實(shí)現(xiàn)單例模板詳解
在我們?nèi)粘i_發(fā)中,無可避免需要使用單例模式進(jìn)行設(shè)計(jì)類對(duì)象。這篇文章主要介紹了如何使用宏函數(shù)實(shí)現(xiàn)單例模板,感興趣的小伙伴可以了解一下2023-02-02C/C++實(shí)現(xiàn)捕獲所有信號(hào)的示例詳解
Linux的信號(hào)機(jī)制大部分情況下用不到,但是由于大部分信號(hào)的默認(rèn)處理是終止進(jìn)程,不正確處理會(huì)惹麻煩,所以我們來看看如何使用C/C++實(shí)現(xiàn)捕獲所有信號(hào)吧2024-03-03C++ 使用CRC32檢測(cè)內(nèi)存映像完整性的實(shí)現(xiàn)步驟
當(dāng)我們使用動(dòng)態(tài)補(bǔ)丁的時(shí)候,那么內(nèi)存中同樣不存在校驗(yàn)效果,也就無法抵御對(duì)方動(dòng)態(tài)修改機(jī)器碼了,為了防止解密者直接對(duì)內(nèi)存打補(bǔ)丁,我們需要在硬盤校驗(yàn)的基礎(chǔ)上,增加內(nèi)存校驗(yàn),防止動(dòng)態(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ì)算長(zhǎng)度,字符查找等的函數(shù)2022-03-03