2016-10-11 6 views
17

私は、C++ 14の標準をlibC++とlibstdC++のソースとともに読んで、C++について深く理解しようとしています。さまざまなtype_traitsアイテムの実装は、特にis_move_assignableの2つで異なり、どちらが「正しい」かを判断しようとしています。libC++と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右辺値をとるので、右のようではありません2番目のテンプレートパラメータにconstを適用することです。 libstdC++は__is_referenceableも使用していますが、これは標準の言葉に従いますが、libC++では使用できません。その要件はlibC++のadd_lvalue_referenceadd_rvalue_referenceの使用でカバーされていますか?どちらも独自に__is_referenceableを適用していますか?

それぞれのプロジェクトがソリューションを選択した理由について、私は本当に洞察に感謝します。

+1

参照可能なものについては、その 'const'は無意味です(参照型に適用するとcv修飾子は無視されます)。 –

+0

@ T.C。ありがとう!作者が 'const'を追加した理由は何ですか? –

+8

多くの場合、次のような応答時間を得ることはできません:https://github.com/llvm-mirror/libcxx/commit/a75b75f514c5c92c8ad8d304b76a01a979b6134c :-) –

答えて

6

:-)より多くのテストを記述する必要があるよう

が見える、2つの実装は、同じことを行います。

(差分から判断すると、それは確かにis_copy_assignableの(間違った)実装からC & Pの問題であるように思わ:)私には、一時的な狂気のように見えます。)

参照不可能(すなわち何のために、 cv voidまたはabominable関数タイプ)、libstdC++はfalse_typeを返します。

libC++では、add_{l,r}value_referenceは変更しません(これはC++ 14以降の問題解決に依存します)。上にconstを散布するとAFTには何も起きず、voidタイプにはconstが追加されます。 T == U == some AFTまたはT == some void typeU = some const-qualified void typeのいずれかのために、declval<T>() = declval<U>()の整形をSFINAEは、テスト

私たちは、その後is_assignableに行き、。すべての場合において、表現は(SFINAEに優しい方法で)間違って形成されているので、我々はfalse_typeを返す。

2つは同等です。

5

__is_referenceableは、標準ではない内部のlibstdC++ルーチンです。 (それは悪いことではない、ちょうど私がlibC++にそれを使うことを期待しているわけではない)。また、「参照可能」という概念は、is_move_assignableよりもずっと後に来た。

__is_referenceableは、「嫌な機能」を扱うときに役立ちます。 int (*) (double) &&のようなものです。 libcの余分なconstが++無意味にも無害であるので、私が参照可能何のために

+0

libC++は、実際には 'add_lvalue_reference'と' add_lvalue_reference'の実装に '__is_referenceable'を定義しています。 'add_rvalue_reference'を使用して' __is_referenceable'を "暗黙的に"適用すると、libstdC++の明示的な '__is_referenceable'の使用と同じ動作が常に得られるかどうかはわかりませんでした。もしそれが意味をなさないなら、ごめんなさい。 –

+0

'(*)'はそこにあるべきではありません:) –

関連する問題