2016-10-11 32 views
17

我想通過閱讀C++ 14標準以及libC++和libstdC++的源文件來深入理解C++。各種type_traits項目的執行情況在兩者之間有所不同,尤其是is_move_assignable,我試圖找出哪些是「更正確的」。libC++ vs libstdC++ std :: is_move_assignable:哪一個最正確?

的libC++:

template <class _Tp> struct is_move_assignable 
    : public is_assignable<typename add_lvalue_reference<_Tp>::type, 
          const typename add_rvalue_reference<_Tp>::type> {}; 

的libstdC++:

template<typename _Tp, bool = __is_referenceable<_Tp>::value> 
    struct __is_move_assignable_impl; 

template<typename _Tp> 
    struct __is_move_assignable_impl<_Tp, false> 
    : public false_type { }; 

template<typename _Tp> 
    struct __is_move_assignable_impl<_Tp, true> 
    : public is_assignable<_Tp&, _Tp&&> 
    { }; 

template<typename _Tp> 
    struct is_move_assignable 
    : public __is_move_assignable_impl<_Tp> 
    { }; 

標準狀態:

對於可引用類型T,相同的結果​​,否則false

我注意到的第一件事是,libc中++應用const到第二個模板參數,這看起來不正確,因爲此舉賦值運算符需要一個非const右值。 libstdC++也使用__is_referenceable,它遵循標準的措辭,但libC++不符合。 libC++使用add_lvalue_referenceadd_rvalue_reference是否滿足這個要求,它們都自己執行__is_referenceable

我真的很感謝每個項目爲什麼選擇他們的解決方案!

+1

對於任何可引用的參數,'const'是無意義的(當應用於引用類型時,cv-qualifiers被忽略)。 –

+0

@ T.C。謝謝!任何想法爲什麼作者可能添加了'const',那麼? –

+8

通常情況下你可以得到這樣的響應時間:https://github.com/llvm-mirror/libcxx/commit/a75b75f514c5c92c8ad8d304b76a01a979b6134c :-) –

回答

6

對於任何可參考的兩種實現方式做同樣的事情,因爲在libc中的外來const ++是沒有意義的,但也無害。

(從差異來看,它肯定看起來像一時失去理智給我:)似乎是一個C & P問題從(錯誤)的實施is_copy_assignable

對於任何非可引用(即, cv void或可惡的函數類型),libstdC++返回false_type

在libC++中,add_{l,r}value_reference將其返回爲無變化(這取決於後置C++ 14的問題解決方案)。在頂部噴灑const對於AFT不做任何處理,並且爲void y類型添加const

然後,我們去is_assignable,這SFINAE檢驗的declval<T>() = declval<U>()的良好性,對於任何一個T == U == some AFTT == some void typeU = some const-qualified void type。在所有情況下,這個表達方式都是不健全的(用SFINAE友好的方式),所以我們回到false_type

這兩者是等效的。

5

__is_referenceable是一個非標準的內部libstdC++例程。 (這並不意味着它不好,只是我不希望libC++使用它)。此外,「可參考」概念比is_move_assignable晚得多。

__is_referenceable有助於處理「惡劣的功能」;例如int (*) (double) &&

看起來我需要編寫更多的測試,:-)

+0

libC++實際上爲'add_lvalue_reference'的實現定義了'__is_referenceable', add_rvalue_reference',但我不確定是否通過使用'add_rvalue_reference'隱式地應用'__is_referenceable'將始終產生與libstdC++顯式使用'__is_referenceable'相同的行爲。對不起,如果沒有意義。 –

+0

'(*)'不應該在那裏:) –

相關問題