2016-07-27 30 views
3

對於std::anystd::variant我們擁有的功能,要求有關當前包含值的對象,返回nullptr如果要求不能被滿足(就像dynamic_cast一樣):std :: any_cast()和std :: get_if(std :: variant)是否需要將指針作爲參數?

template<class ValueType> 
const ValueType *any_cast(const any *operand); 

template<class ValueType> 
ValueType *any_cast(any *operand); 

template <class T, class... Types> 
std::add_pointer_t<T> get_if(variant<Types...> *pv); 

template <class T, class... Types> 
std::add_pointer_t<const T> get_if(const variant<Types...> *pv); 

兩個以指針作爲參數。爲什麼?這不是有效的。該實現每次都檢查參數是否不是nullptrnullptr爭論是否有意義?

此函數可以是類成員,也可以是引用作爲參數(名稱可能略有不同)。這是不是最理想的設計的原因是什麼?只是模仿dynamic_cast界面?

+4

您正在使用類型擦除容器並獲取其存儲的值,並且您擔心與'nullptr'比較的性能? –

+1

是的。我擔心每個可避免的開銷。它只是醜陋的界面 –

+1

這些函數的版本以參考爲參數。他們只是拋出失敗(而不是返回'nullptr')。 – Barry

回答

4

爲了保持DOWNTO其中的一個功能,並使其像buikt工作,_cast運營商,any_cast作品有任何引用或指針。

指針版本需要一個指針,如果它包含你所要求的,則返回一個指向元素的指針。否則它返回nullptr。

參考版本需要引用,如果它不包含您要求的內容,則會拋出。

他們使用參數的指針來區分這兩個選項,匹配dynamic_cast<T&>(x)dynamic_cast<T*>(&x)的工作方式。

這將很容易內聯。對指向自動存儲對象的指針進行內聯檢查很容易優化爲「不爲空」,因爲自動存儲對象的地址沒有適合的方式爲nullptr。

因此,幾乎在每個發行版中,我都希望check-if-nullptr的開銷爲零。一個例外是代碼有一個指向任何(或變體)的指針,它有一些證據證明這個指針對任何非空的編譯器不太可能知道,然後它傳遞給any_cast。如果他們沒有使用指針指向指針返回類型的技巧,那麼可以用UB代替any_cast_to_ptr(any&)並無條件地解引用指針。

真正的API缺少的是dangerous_any_cast,這根本就UB如果類型不匹配,因爲非局域證明有關any的狀態知識似乎比約的指針到任何無效非局域成熟的知識更容易。

這種情況很少見。

至於get_if vs get,我不知道爲什麼沒有get_if(variant<???>&)過載。

+3

'get_if'只是指針。參考/投擲版本是'get'。 –

相關問題