2017-03-10 52 views
1

比方說,我們有一個變量是否有可能在std ::可選w/o中放置一個實例來檢查/破壞前一個實例?

std::optional<T> x; 

std::optional<T>類型的某種類型的T。 如果我想在x中調用T的構造函數並初始化它,我可以調用成員函數std::optional::emplace。據我所知,這個成員函數檢查實例是否已經存在(即bool(x)求值爲true),如果是這種情況,它首先銷燬先前構造的實例,然後使用提供的構造函數和參數重新初始化它。

我想知道是否有可能做只有初始化W/O檢查和銷燬。在處理std::optional時,首先檢查實例是否存在,然後根據結果做一些單獨的工作似乎很常見。因此,似乎有理由認爲,當我們需要在std::optional內部放置一個實例時,我們已經知道它不包含任何已初始化的實例。因此,提供std::optional::emplace的「不安全版本」似乎是合理的,它不檢查和銷燬先前的實例,但std::optional不具有這樣的成員函數。有什麼辦法可以做到這一點?

也許,如果有關於內存佈局std::optional一些擔保(我想不會),那麼我可以呼叫部署new運營商直接...

+0

我希望一個體面的優化編譯器將能夠刪除這些無用的檢查。您是否在優化之後檢查此檢查是否仍然存在? – JVApen

+0

@JVApen看起來經常是這樣,但並非總是如此,特別是當在另一個函數(編譯器未能內聯)中完成構造時。 –

+0

你是否已經嘗試添加斷言是空的? – JVApen

回答

2

不,這是不可能的。而且,不,調用new直接放置到內存上也無濟於事,因爲您還必須在optional中設置標誌,表示optional已啓用 - 並且您無法在外部執行此操作。

因此,似乎有理由認爲,很多時候,當我們需要佈設內std::optional一個實例,我們已經知道,它不包含任何初始化實例

這不是一個有力的論據。 emplace()僅僅是operator=之上的潛在優化,在使用關於optional的當前狀態的這樣的函數時沒有暗示的暗示。

另外,如果你的代碼的結構類似於:

if (!o) { 
    // stuff 
    o.emplace(some, args, here); 
} 

你可以放心,你的編譯器會看到explicit operator bool()檢查和內部emplace()檢查之間的重複分支和摺疊在一起,所以不會有成爲一個額外的分支。

+0

「關於內存佈局的保證」我的意思是包含關於flag變量位置的保證。我沒有理由不提供「emplace」的「暗示」版本和普通版本。我認爲,諸如'unsafe_emplace'這樣的名稱很可能會阻止程序員過度使用它。我查看了生成的程序集,並且進行了雙重檢查,因爲儘管存在最大化優化標記,但編譯器未能內聯「std :: optional :: emplace」。 –

相關問題