23

移動セマンティクスを利用したいが、可動クラスの 1 つが の一部である必要があるとしますstd::pairstd::pair目的は、右辺値として扱うことができ、一緒に転送できるを返す関数を作成することです。

std::pairしかし、移動セマンティクスを認識させるために、それ自体に内部的な変更が加えられない限り、これがどのように行われるのかわかりません。

次のコードを検討してください。

struct Foo
{
 Foo() { }

 Foo(Foo&& f) { }

 private:

 Foo(const Foo& f) { } // do not allow copying
};

int main() 
{
 Foo f;
 std::pair<Foo, int> res = std::make_pair(f, 10); // fails due to private copy constructor
}

問題はstd::make_pair、コンストラクタ自体と同様に、std::pair2 つのオブジェクトを取り、それらの内部コピーを作成しようとすることです。これにより、コピー コンストラクターの呼び出しが試行されます。しかし、私の例では、新しいペアをに移動resし、コピーが作成されないようにしたいと考えています。std::pair内部で次のコンストラクターが定義されていない限り、これは不可能だと思います。

pair(T1&& t1, T2&& t2) : first(std::move(t1)), second(std::move(t2))

しかし、少なくとも私が使用しているコンパイラ(gcc 4.3.2)ではそうではありません。私のコンパイラが単に古くなっている可能性があり、実際には新しいバージョンにはこのムーブ対応コンストラクタがあります。しかし、現時点では移動のセマンティクスに関する私の理解はやや不安定なので、ここで何かを見落としているだけなのかどうかはわかりません。それで、実際に再実装せずに、私が達成しようとしていることは可能std::pairですか? または、コンパイラが古くなっていますか?

4

2 に答える 2

20

std::pairただし、それは呼び出されるコンストラクターではありません。移動コンストラクターが呼び出され、std::pair移動コンストラクターは期待どおりに動作するはずです (N3126 20.3.5.2/6):

template<class U, class V> pair(pair<U, V>&& p);

効果: コンストラクターは、最初に で初期化し、次に で初期化std::move(p.first)std::move(p.second)ます。

ただし、 inは左辺値であり、明示的に d にする必要があるため、例は失敗するはずです。そうでない場合はコピーされます。以下が機能するはずです。std::make_pair(f, 10);fmove

std::pair<Foo, int> res = std::make_pair(std::move(f), 10);
于 2010-11-04T14:26:32.440 に答える
2

GCC 4.3.2 には、完全な実装があってはなりません。ペア (およびタプル) には移動コンストラクターが必要です。

template<class U, class V> pair(U&& x, V&& y);
効果: コンストラクターは最初に std::forward(x) で初期化し、次に std::forward(y) で初期化します。
template<class U, class V> pair(pair<U, V>&& p);
効果: コンストラクターは最初に std::move(p.first) で初期化し、2 番目に std::move(p.second) で初期化します。

(n3126の[pairs.pair]より)

于 2010-11-04T14:29:34.123 に答える