我有多个返回std::optional<T>
. 这是一个虚构类型的示例MyType
:
struct MyType {
// ...
}
std::optional<MyType> calculateOptional() {
// ... lengthy calculation
if (success) {
return MyType(/* etc */);
}
return std::nullopt;
}
让我们假设这些函数的运行成本很高,我想避免多次调用它们。
当调用它们时,我想立即测试可选项,如果它确实包含一个值,我想立即使用它并且不再使用它。例如,在 Swift 中,我可以使用标准if-let
语句:
if let result = calculateOptional() {
// Use result var
}
我想在 C++ 中复制这种测试和解包行为,同时在使用时保持代码尽可能干净。例如,显而易见的简单解决方案(至少对我而言)是:
if (auto result = calculateOptional()) {
MyType result_unwrapped = *result;
// Use result_unwrapped var
}
但是您必须在 内展开if
,或*result
在任何地方使用,这与 Swift 无关。
到目前为止,我唯一真正接近 Swift 外观和感觉的解决方案是:
template<typename T> bool optionalTestUnwrap(std::optional<T> opt, T& value) {
if (!opt.has_value()) { return false; }
value = *opt;
return true;
}
#define ifopt(var, opt) if (typename decltype((opt))::value_type (var); optionalTestUnwrap((opt), (var)))
ifopt (result, calculateOptional()) {
// Use result var
}
...但我也不喜欢使用宏来替换普通if
语句。