網(wǎng)站首頁 編程語言 正文
前言
平時寫代碼會遇到一種傳遞參數(shù)特殊值標(biāo)記特殊流程,或者函數(shù)返回值存在魔法數(shù)的情況,很需要一種標(biāo)記參數(shù)或返回值狀態(tài)的結(jié)構(gòu),那么在 C++17 標(biāo)準(zhǔn)下提供了 std::optional 這個模板類,可以表示一個值不存在的狀態(tài),一起來看看用法吧。
返回一個bool值
以下例子純屬虛構(gòu),只為說明問題,無實際意義
bool getBoolVal(int a, int b)
{
? ? int* n = new int;
? ? if (!n)
? ? ? ? return false;
? ? *n = 1;
? ? if (a + *n > b)
? ? ? ? return true;
? ? else
? ? ? ? return false;
}
int main()
{
? ? if (getBoolVal(10, 9))
? ? ? ? std::cout << 1 << std::endl;
? ? else
? ? ? ? std::cout << 1 << std::endl;
? ? return 0;
}
這個例子中的函數(shù) getBoolVal 本意是想返回一個 bool 類型的判斷結(jié)果,但是函數(shù)中有一些異常情況時,比如申請內(nèi)存異常時,也會返回一個bool值,這是與原判斷結(jié)果語義不同的,所以需要單獨返回這種情況,如果也放到同一個返回值中會導(dǎo)致含義模糊,這時可以考慮使用引用變量參數(shù)來返回實際比較結(jié)果。
bool getBoolVal(int a, int b, bool& ret)
{
? ? int* n = new int;
? ? if (!n)
? ? ? ? return false;
? ? *n = 1;
? ? if (a + *n > b)
? ? ? ? ret = true;
? ? else
? ? ? ? ret = false;
? ? return true;
}
int main()
{
? ? bool ret = false;
? ? if (getBoolVal(10, 9, ret))
? ? ? ? std::cout << "error" << std::endl;
? ? else
? ? {
? ? ? ? if (ret)
? ? ? ? ? ? std::cout << 1 << std::endl;
? ? ? ? else
? ? ? ? ? ? std::cout << 0 << std::endl;
? ? }
? ? return 0;
}
這個引用參數(shù) ret 使用起來有點不方便,那把兩個值都返回怎么樣,雖然C++不允許有多個返回值,但可以把它們包裝成 std::pair 或者 std::tuple 來返回,再來改寫一下:
std::pair<bool, bool> getBoolVal3(int a, int b)
{
? ? int* n = new int;
? ? if (!n)
? ? ? ? return {false, false};
? ? *n = 1;
? ? if (a + *n > b)
? ? ? ? return {true, true};
? ? else
? ? ? ? return {true, false};
}
int main()
{
? ? auto [err, ret] = getBoolVal(10, 9);
? ? if (err)
? ? ? ? std::cout << "error" << std::endl;
? ? else
? ? {
? ? ? ? if (ret)
? ? ? ? ? ? std::cout << 1 << std::endl;
? ? ? ? else
? ? ? ? ? ? std::cout << 0 << std::endl;
? ? }
? ? return 0;
}
這種方法把實際的返回值,搭配一個表示狀態(tài)的 bool 變量,組成 std::pair 進行返回,基本上得到而來語義明確的目的,但是看起來還是不太優(yōu)雅,而 std::optional 可以幫助我們實現(xiàn)類似的需求,并且代碼看起來能更簡潔一點。
使用 std::optional 改寫
std::optional 本身是一個模板類:會有一個 std::nullopt
template <class T>
class optional;
它內(nèi)部有兩種狀態(tài),要么有一個T類型的值,要么用 std::nullopt 表示沒有值,查看一個 std::optional 對象是否有值,可以用 has_value() 進行判斷,當(dāng)一個 std::optional 有值時,可以通過用指針的方式(*號和->號)來使用它,或者用 value()函數(shù)取它的值,下面我們用它來改寫一下之前的實現(xiàn):
std::optional<bool> getBoolVal4(int a, int b)
{
? ? int* n = new int;
? ? if (!n)
? ? ? ? return std::nullopt;
? ? *n = 1;
? ? if (a + *n > b)
? ? ? ? return true;
? ? else
? ? ? ? return false;
}
int main()
{
? ? std::optional<bool> ret = getBoolVal(10, 9);
? ? if (ret.has_value())
? ? ? ? std::cout << "error" << std::endl;
? ? else
? ? {
? ? ? ? if (ret.value())
? ? ? ? ? ? std::cout << 1 << std::endl;
? ? ? ? else
? ? ? ? ? ? std::cout << 0 << std::endl;
? ? }
? ? return 0;
}
使用了 std::optional 之后就把 bool 類型之前的兩態(tài)變成了三態(tài),很多類似的邏輯也被封裝成了函數(shù),使用它之后代碼更清晰了,從此可以告別一些煩人的魔法數(shù)了,一些函數(shù)參數(shù)也可以使用 std::optional 來包裝,用法類似,在此就不展開說了。
總結(jié)
- std::optional 是一個模板類,可以表示一個可能存在的值
- std::optional 的內(nèi)部有兩種狀態(tài),要么表示一個T類型的值,要么用 std::nullopt 表示沒有值
- 可以用 has_value() 判斷一個 std::optional 是否有值,然后用 value() 函數(shù)取它表示的值
原文鏈接:https://blog.csdn.net/albertsh/article/details/125839078
相關(guān)推薦
- 2022-07-29 Linux磁盤管理方法介紹_linux shell
- 2022-04-27 Python中的元組(Tuple)操作實例詳解_python
- 2023-02-04 Golang中for循環(huán)的用法示例詳解_Golang
- 2022-06-23 android中的adb命令學(xué)習(xí)_Android
- 2023-11-15 latex報錯:Misplaced alignment tab character &. .
- 2022-09-30 Python測試框架pytest核心庫pluggy詳解_python
- 2022-07-28 Redis特殊數(shù)據(jù)類型HyperLogLog基數(shù)統(tǒng)計算法講解_Redis
- 2022-10-26 Google?Kubernetes?Engine?集群實戰(zhàn)詳解_云其它
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支