2013-06-17 8 views
18

を移動::静的キャストの説明は静的キャストとの間の差は

言う右辺値参照とSTDにあるnew_typeは右辺値参照型である場合、static_castをははxValueに式の値を変換します。このタイプのstatic_castは、std :: moveでの移動セマンティクスの実装に使用されます(C++ 11以降)

これは、以下が等価であることを確認していますか?

(A)

X x1; 
X x2 = static_cast<X&&>(x1); 

(B)

X x1; 
X x2 = std::move(x1); 
+4

のようなものです。 – user1353535

答えて

31

はい非常に重要な違いがある:あなたが何をしたいかstd::move文書。さらに、キャストには、忘れた&や間違ったタイプのXのような書き込みエラーが発生しやすくなります。

明らかにわかるように、std::moveは入力することがさらに少なくなります。

+3

私は '' static_cast ''を' 'move'が' 'constexpr'ではないときにのみ使用し、その属性が必要です。 – CTMacUser

1

& &では、C++ 11はrValueリファレンスです。それらはC++ 98,03からの左辺値参照のように振る舞います。彼らの目標 - 動く候補者になること。 C++ 98では、このような構造はリフレクションの崩壊に現れる可能性があります。

std :: move - rvalueで表現を変えます。 rvalue_castとすることもできますが、そのようなキーワードは存在しません。

原則としてT & &への明示的キャストが可能です。本当のスタンダールは、いくつかのお金がかかるが、ISO/IEC 14882:2011 のドラフトで

5.2.9静的

8)

左辺値ツー右辺値(4.1)、配列をキャストし、そのような情報に存在してあります実用的な観点から-to-ポインタ(4.2)、および機能へのポインタは、(4.3)変換が オペランドに適用される....

スタンダード::移動を使用する方が便利です。 は、例えば想像:1回目のアプローチは

  • より便利である私として

    #include <stdio.h> 
    #include <utility> 
    
    class A 
    { 
    public: 
    A() {printf ("A()" "\n");} 
    A (const A &) {printf ("A (&)" "\n");} 
    A (A &&) {printf ("A (&&)" "\n");} 
    A (const A &&) {printf ("A (const &&)" "\n");} 
    ~ A() {printf ("~ A()" "\n");} 
    }; 
    
    
    int main() 
    { 
    const A obj; 
    A obj2 (std::move (obj)); // 1-st approach 
    A obj3 (static_cast <const A&&> (obj)); // 2-nd approach 
    } 
    

    を(あなたが& &のconst A & &に、またはにはstatic_castを行う必要がありますか?あるとき)

  • は、より明示的に(私は、プロジェクト内のstd ::移動)
  • が少ないエラーが発生しやすいソフトウェア開発者の書き込みコード
+0

'rvalue_cast' _keyword_は必要ありません。テンプレートテンプレート constexpr auto rvalue_cast(T && t){std :: move(t)を返します。 };もしあなたが本当にその名前を使用したいならば。 – rubenvb

-1

あなたはstatic_cast<A &&>(a)を使用することができますを見つけるために、テキスト・エディタで検索を使用することができます右値ですが、std::move(a)は使用しないでください。
A && a = std::move(A())を使用すると、手間のかかる参照が発生します。

基本的な考え方は、一時的にバインドされた参照から初期化された第2の参照は、その存続時間に影響しないということです。

std::moveの実装では、彼らは同じものですが、動きが発生しやすい小さい誤差でやや

template <typename T> 
constexpr decltype(auto) move(T && __t) noexcept // when used in std::move(A()), 
                // the lifetime of the temporary object is extended by __t 
{ 
    return static_cast<typename std::remove_reference<T>::type &&>(__t); // a xvalue returned, no lifetime extension 
} 

auto && a = std::move(A()); // the anonymous object wiil be destructed right after this line 
+0

2番目の例では、どのように参照がぶら下がっているのかわかりません。また、 'a'がrvalueのとき' std :: move(a) 'の何が問題になりますか? 'std :: move((const int&)a)'の結果はちょうど 'const int &&'です。これはあなたが望むものです。 – SirGuy

+0

@SirGuy関数呼び出しの参照パラメータへの一時的なバインドは、その関数呼び出しを含む完全な式の終わりまで存在します。関数が参照を返し、完全な式を超えた場合、参照がぶら下がり参照になります。 'move'は、キャストされたprvalue式を引数としてrvalue参照をとります。 –

+0

'A && a = std :: move(A());'はダングリングリファレンスになります(同じもののstatic_castバージョン)... 'A a'はリファレンスではないので、ダングリングなものではありません –

関連する問題