要防呆,它需要:哪個C++功能可以確保從選項<T>中提取T&T?
- 清晰的語法
- 可能使用
auto
- 原子的使用,以防止意外的失誤像
if (!opt) { opt->call(); }
- 沒有運行時斷言(編輯 :和例外)
- 無編譯器警告
- (可選)無靜態檢查器警告GS
到目前爲止,我已經試過這4個選項(假設具有可變optional<T> opt;
):
選項0標準用法
if (opt) {
opt->call();
}
- +清潔代碼
- +自然控制流量,有
else
聲明 - -不是原子
- -
operator->
在可空類型被暴露,所以很容易調用opt->call()
無if
檢查
選項1.創建一個智能指針almost_present<T>
與_DEBUG
-只有字段mutable boolean checkedPresent
設置爲true
當用戶確實operator bool
:
if (almost_present<T> nonull = opt.if_present()) {
// `operator->()` and `operator T&()` assert if called without doing `if (nonull)`
nonull->call();
T& x = nonull;
}
- +自然控制流程,具有
else
聲明 - +將斷言,如果用戶沒有引用之前檢查值,即使它是目前
- -運行時檢查
- -
almost_present<T>::operator bool() const
必須修改checkedPresent
字段 - -可能會意外地在
else
分支使用nonull
,但這是次要的
選項2。範圍爲基礎的循環招從http://loungecpp.net/cpp/abusing-range-for/:optional<T>
或optional<T>::if_present()
實現方法begin()
和end()
看起來像0或1項
for (auto& nonull : opt.if_present()) {
nonull.call();
}
- +集合簡潔的語法
- -無條件
return
在任何迴路內產生warning C4702: unrechable code
(VC2017) - -沒有
else
聲明,必須單獨調用if (!opt)
,這不是原子 - -看起來像一個循環,可能會誤解,如果
T
是一家集
選項3 Lambda表達式
opt.if_present([](auto& nonull) { nonull.call(); });
auto result = opt.map(
[](auto& nonull) { return nonull.call(); },
[]() { return what_if_null(); }
);
- +它的工作原理
- -沒有一個清晰的語法 - 難以閱讀和調試
現在,我使用的組合 「for」 循環和 「lambda表達式」
幾乎目前看起來對我來說是可選的。 – Yakk
除了娛樂之外,我不會使用.2和.3。這種代碼有效地混淆了。 – Pavel
@Yakk,'almost_present'如果您忘記了'if',則會預防性地斷言,所以用1個測試覆蓋此代碼就足夠了。而'std :: optional'只會在你傳遞一個空值時失敗,這可能非常少見。 –