2016-05-17 4 views
2

手続きを外しましょう。std :: move(x)で何らかの操作を実行

そのタイプ

ため を指定されているように挙動オブジェクト上

17.3.28有効ですが、不特定の状態[defns.valid]

オブジェクトオブジェクトの 不変条件が満たされていることを除いて指定されていない状態と操作

[例:タイプstd::vector<int>の目的xx.empty()無条件 、及び0123呼び出すことができ、有効ではなく不特定の状態である場合は、x.empty()が を返した場合にのみ呼び出すことができます。 - 最後の例]

一部のユーザーはstd::move(x).something()が無意味であることを示唆しています。しかし、std::move(x).something()y = std::move(x); y.something()の違いを理解できません。お守り:

// -D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC 
std::vector<int> v; 
v.pop_back(); 
// Error: attempt to access an element in an empty container. 

今、我々は無意味な場合試してみたい:

std::vector<int> v(10); 
std::move(v).pop_back(); 

エラーはありませんが。これは誰もが話している「有効だが不特定」でなければならないが、続けよう。

std::vector<int> v(10); 
std::cout << std::move(v).size(); 
auto v2 = std::move(v); 
std::cout << v.size(); 

これは100を印刷します。それほど驚くべきことではない。 std::moveは単なるキャストであり、実際には移動コンストラクタのジョブを実行しません。

何かが見つからないのですか、まだstd::move(x).something()はノンオプティカルではありませんか?


参考までに、Member function .begin() and std::begin()のコメントとアップアップされた回答を参照してください。

template< class C > 
auto begin(C&& c) -> decltype(c.begin()) 
{ 
    return c.begin(); 
} 

int main() 
{ 
    std::vector<int> v(10); 
    std::vector<int>::iterator it3 = begin(std::move(v)); 
    std::cout << v.size(); 
} 

出力10

次の例では、vから移動しないことを示唆しています。

+3

'std :: move(v)'は 'v'に何もしません。 'std :: move(v).pop_back();'は 'v.pop_back();'と同じ効果を持ちます(ただし、すべての型に一般化することはできません)。あなたが投稿した見積もりには、いくつかの文脈がありません。 – juanchopanza

+0

@juanchopanza私の文脈は[this](https://stackoverflow.com/questions/37262329/member-function-begin-and-stdbegin)から来ます。 "' begin'のようなコメントは根底にある範囲がもはや存在しないのであまり有用ではないので、rvalueのオーバーロードを持つことは有益ではないようです。 「理論的には、標準コンテナは、rvalueコンテキストで 'std :: begin'で呼び出されるのに適切な対応をしていません。' std :: move'または 'rvalues 'とのやり取りの「適切な」方法は、呼び出しが完了した後に移動元のオブジェクトの状態を気にするはずです。私が紛失していることを示唆しているようです。 –

+0

@juanchopanza言い換えれば、 'std :: begin(std :: move(x))'や 'std :: move(x).begin()'は 'std :: begin(x)'と同じです。 'x.begin()'?では、ロジックはどこから来ていますか? –

答えて

6

std::moveはオブジェクトに何もしません!それが行うのは、キャストのオブジェクトであり、それはr値の参照によって束縛されることができます。

オブジェクトへの変更は、対応する移動コンストラクターまたは移動アサイメント演算子によって行われます。何も呼ばれなければ、何も起こりません。

+0

s/converting/cast – Barry

+0

@Barryは同意します。 – SergeyA

0

しかし、私は

struct S 
{ 
    void foo() const & {std::cout << "l-value this\n"; } 
    void foo() const && {std::cout << "r-value this\n"; } 
}; 

const&/&&に注意)でstd::move(x).something()y = std::move(x); y.something()

の違いを理解し、トラブルを抱えているあなたは得た:

S tmp; 
std::move(tmp).foo(); // "r-value this 

S x = std::move(tmp); 
x.foo(); // "l-value this 
関連する問題