1

またおかしなことをしようとしている。

さて、これが一般的な考え方です。含まれるオブジェクトを実際に所有するstd::list(など) が必要です。値をそこに移動し、参照によってアクセスしvectorたいと思います。

unique_ptr のリストを使用した例:

using namespace std;
list<unique_ptr<T>> items;     // T is whatever type
items.push_back(make_unique(...));
items.push_back(make_unique(...));

for ( unique_ptr<T> item : items )
    item.dosomething();

ここまで私と?良い。それでは、スタック セマンティクスと右辺値参照を使用して実行してみましょう。list<T&&>明らかな理由でa を使用することはできないため、新しいクラスを作成する必要があります。

using namespace std;
owninglist<T> items;
items.push_back(T());
items.push_back(T());

for ( T& item : items )
    item.dosomething();

もちろん、owningstackorも必要かもしれないowningvectorので、理想的にはテンプレート化する必要があります。

owning<std::list<T>> items;

クラスは、基礎となるコレクションが持つ関数などをowning<U<T>>継承する必要があります。おそらくそれを達成するには、ジェネリック基本クラスをコーディングし、通常とは異なる機能を持つコレクションの明示的な特殊化を導出する必要があります。push_back()pop_front()

template<typename T> owning<std::queue<T>> : owningbase<T> {
    void push_front() { ... }
}

イテレータで行き詰まっています。begin()and関数は、値ではなく左辺値参照によって項目を返すend()を除いて、基になるコレクションの反復子と同じように機能する反復子を返す必要があります。operator*()

項目の所有権をリストから再度移す何らかの方法が必要です。おそらく、イテレータは、アイテムをrvalueoperator~として返し、リストからアイテムを削除し、イテレータを無効にする を持つことができますか?

もちろん、これはすべて、基礎となるstd::listもの (またはその他のもの) が右辺値を取ると確信できることを前提としています。値push_back()を左辺値としてコピーすると、これは機能しません。コンテナを最初からコーディングしたほうがよいでしょうか? 私がした場合list、 、queuestackおよびのコードの大部分をvector単一の基本クラスに入れて、ほとんど同じクラスを4回書き直すのを節約する方法はありますか?

おそらく、中間クラス、ある種のラッパーを導入できますか? それで、何かowned<list<T>>から継承できlist<refwrapper<T>>ますか?ブーストに があることは知っていますがreference_wrapper、このシナリオに適合するかどうかはわかりません。

4

1 に答える 1

1

コピー要素を回避したい場合は、std::move を使用できます。

したがって、 std::list がある場合は、値を移動して値を入力できます。

SomeBigObject sbo;

std::list<SomeBigObject> list;
list.push_back(SomeBigObject()); // SomeBigObject() is a rvalue and so it is moved
list.push_back(std::move(sbo));  // sbo may not be a rvalue so you have to move it

// For construction you can also use std::list::emplace
list.emplace(list.end());        // construct the value directly at the end of the list

それらにアクセスするには、単純に範囲ベースのループを使用できます。

for(auto& i :list)
    ...

それらをコンテナーの外に移動する場合は、std::move を使用することもできます。オブジェクトはコンテナから移動されますが、残りはコンテナ内に残るため、それらを消去する必要があります。

for(auto it = list.begin; it != lsit.end();)
{
    // the value of *it is moved into obj;
    // an empty value of "SomeBigObject" will remain so erase it from the list
    SomeBigObject obj = std::move(*it);

    it = list.erase(it);

    // do something with "obj"
    ...
}
于 2013-06-04T16:16:19.133 に答える