什么是std::optional?
C++17中新引入了std::optional<T>
。類模板std::optional
管理一個可選的容納值。簡單說來,std::optional
就是一個和類型,常見的用處就是作為函數返回值來處理一個可能失敗的函數。
如何處理無參返回?
此前處理無參返回的函數一般有兩種方式。
第一種:
bool foo(int param1, int*param2);
返回參數作為引用/指針型輸入參數而存在,傳入地址,在執行完畢后訪問指定地址得到返回值,而使用真正的返回值來作為函數是否成功的返回。
這種方式可以實現需求。
缺點是:
- 浪費存儲空間——無論是否返回值,都需要做好有值的准備,
param2
的空間需要事先分配 - 可讀性/可用性差——同為參數,有的是輸入參,有的是輸出參,即使以名字取分,使用的時候也比較困難。
第二種:
std::pair<T,bool>foo(int param1);
這是比較常用的方式,解決了問題2——每次使用都知道返回值是pair
的第一個值,第二個值專門用於成功與否的判斷。
不過std::optional
繼續優化了處理方式。
正如前述,std::optional
管理的是可選的容納值。如果函數成功執行,則實例含值,如果執行失敗,實例不含值。
如何處理多參返回?
這都不是個問題,class
,struct
,哪個都比直接放在一個tuple
里面或者更過分的直接列在函數參數里面好。
使用std::optional
- 定義位置:
<optional>
- T:一個滿足可析構的類型
- 初始化:
- 使用
=
用另一個T
類型含值std::optional
初始化 - 使用構造函數初始化:以
nullopt_t
類型值或是T
類型值 - 默認構造函數
- 使用
- 是否含值:
- 使用
bool hasValue=temp.has_value()
檢查是否含值
- 使用
- 取值:
- 使用
(*temp)
取T
,即默認為T
的指針 - 使用
temp.value()
獲取T
值 - 使用
temp.value_or()
獲取值(存在值)或者其他(不存在值)
- 使用
- 返回:
- 一個
T
對象(非指針) nullopt
{}
- ...
- 一個
一個實例:
//一個可析構類型
class Test{
int num1;
int num2;
Test(int n1,int n2){
num1=n1;
num2=n2;
}
bool isOK(){
return num1+num2>=0?true:false;
}
}
//一個可能執行失敗的函數【有點草率,看看語法就好
std::optional<Test>foo(int num){
Test t(num,num);
if(t.isOK()){
//返回正常對象
return t;
}
//返回空值
return nullopt;
}
int main(){
int myAge=20;
//一種賦值方式
std::optional<Test>opt=foo(myAge);
//一種判斷是否含值的方式
if(opt.has_value()){
//foo函數成功執行
//一種取值方式
cout<<(opt.value()).num1<<endl;
}
}
Reference
cppreference-std::optional 更多特性/支持的操作請訪問
C++17 新特性之 std::optional(上)更好地理解為何使用std::optional請訪問