1

移動のみのタイプがあり、コピーは禁止されています。何らかのシステムでそれを渡したいのですが、その型のパラメーターを受け取る関数にどの種類の署名を使用すればよいかわかりません。このタイプのオブジェクトはシステムに移動する必要があり、コピーは一切行われません。

例:

#include <vector>
class Foo
{
public:
    Foo( std::string name ) : m_name( std::move( name ) ){}
    Foo( Foo&& other ) : m_name( std::move( other.m_name ) ){}
    Foo& operator=( Foo&& other ){ m_name = std::move( other.m_name ); }

    const std::string& name() const { return m_name; }
    // ...
private:
    Foo( const Foo& ) ;//= delete;
    Foo& operator=( const Foo& ) ;//= delete;
    // ...

    std::string m_name;
};

class Bar
{
public:

    void add( Foo foo )  // (1)
        // or...
    void add( Foo&& foo ) // (2)
    {
        m_foos.emplace_back( std::move(foo) ); // if add was template I should use std::forward?
    }


private:
    std::vector<Foo> m_foos;
};

void test()
{
    Bar bar;
    bar.add( Foo("hello") );

    Foo foo("world");
    bar.add( std::move(foo) );
}

(オブジェクトを移動していると仮定すると、両方の署名が VS2012 でコンパイルされます)

1 と 2 のどちらの署名を優先する必要がありますか?

どちらも機能しているように見えますが、違いがあるはずだと思います...

4

2 に答える 2

4

署名#1は、xvalueから移動するときに2移動構築のコストがかかりますが、署名#2は、xvalueから1移動構築のコストがかかります。したがって、#2の方が私にはよく聞こえます。しかし、移動の建設が安価である限り、どちらの署名でも仕事は終わります。欲しいですか:

  1. 本当に速い、または
  2. 本当に速いの2倍の速さ?

:-)

于 2012-09-14T00:25:50.063 に答える
3

場合によります。

オブジェクトを関数に移動する場合は、値で取得します。コンパイラは移動自体を行い、関数が渡された引数を移動することを呼び出し元に明確に文書化します。2 番目を使用すると、呼び出し元が を使用する必要がある場合でも、関数は引数を移動する場合と移動しない場合がありstd::move(foo)ます。それは非常に混乱する可能性があります。

オブジェクトを関数に移動したくない場合は、左辺値参照を取得します。関数が変化しない場合は const にし、変化する場合は非 const にします。

于 2012-09-13T23:25:01.843 に答える