什么是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请访问