2017-07-29 97 views
13

我經常需要使用的功能可選類型:返回可選值有:運營商

std::optional<int32_t> get(const std::string& field) 
{ 
    auto it = map.find(field); 
    if (it != map.end()) return it->second; 
    return {}; 
} 

有沒有辦法在一個行返回可選值?例如這樣的:

std::optional<int32_t> get(const std::string& field) 
{ 
    auto it = map.find(field); 
    return it != map.end() ? it->second : {}; 
} 

導致錯誤

error: expected primary-expression before '{' token 
return it != map.end() ? it->second : {}; 
            ^
+0

@ tobi303'{}'未解析爲表達。 – MiP

+2

Clang給出了一個更好的錯誤消息:「初始化程序列表不能在運算符的右側使用?」 – emlai

回答

20

您可以明確地將某些價值回報換成std::optional,並回退到constexprstd::nullopt以獲得無價值回報。

std::nullopt

std::nullopt是用於 std::nullopt_t類型的恆定指示可選類型與未初始化狀態。

...

std::nullopt_t

std::nullopt_t是用來表示與未初始化狀態可選類型 空類的類型。特別是,std::optional有一個 構造函數,nullopt_t作爲單個參數,這會創建一個不包含值的 可選項。

通過這種方法,三元話務員呼叫的真實子句明確地返回與一些值的std::optional,所以編譯器可推導出的模板的參數/包裹型(在本例中:int32_t)從類型提供的包裝值,這意味着您不需要明確指定它。

應用到您的例子:

return it != map.end() ? std::optional(it->second) : std::nullopt; 

// alternatively 
return it != map.end() ? std::make_optional(it->second) : std::nullopt; 
19
return it != map.end() ? it->second : std::optional<int32_t>{}; 

應該做的伎倆。

編譯器必須從最後兩個操作數推導的三元表達式的結果類型,但沒有辦法它可以從int32_t{}推斷std::optional<int32_t>

int32_tstd::optional<int32_t>另一方面確實有所需的普通型std::optional<int32_t>


相關有趣的事實:你能避免重複與自動返回類型推演類型:

auto get(const std::string& field) 
{ 
    auto it = map.find(field); 
    return it != map.end() ? it->second : std::optional<int32_t>{}; 
} 

根據喜好,你當然也可以從it->seconddecltype推斷爲std::optional模板參數以進一步減少重複。

+0

根據如何聲明map <以及int32_t在編譯時可能會發生變化的程度),你可以走得更遠,並將其模板化。 – Kevin