15

これはおそらく単純な C++ の質問ですが、私は C++ を再学習していて、いくつかの基本を知りません。オブジェクトのベクトルを含む構造体を含むクラスがあるので、次のようになります。

struct my_struct{
    Irrelevant_Object object,
    vector<tuple> tuple_list;
}

構造体とタプル (別の構造体) はアーキテクチャによって事前定義されており、私の方法で提供されます。だから私はそれらを変更することはできません。もともと空のtuple_listにタプルを生成して挿入したい。

簡単な解決策は、新しいタプル オブジェクトを割り当て、タプル データを入力し、tuple_list.push_back() を呼び出して、割り当てられたタプルを渡すメソッドを用意することです。しかし、これには新しいタプルを割り当てるだけで、push_back メソッドで (大きな) タプル構造体のすべての内容をベクトルの定義済みメモリ空間にコピーする必要があります。したがって、割り当て/削除の費用と、タプルの内容をベクターにコピーしてこの方法で行う費用が少なくなります。それはかなり効率が悪いと思われ、このメソッドは関数のクリティカル パスにあるため、より高速な方法を好むでしょう (確かに、このメソッドがボトルネックになるとは思えません。初期の最適化 == 悪いことはわかっています。しかし、私は '

だから私の質問は、タプルを割り当てたりコピーしたりせずに、タプルリストの内容をすばやく埋める方法はありますか? これが配列である場合、配列を必要なだけ大きくすることができ、tuple_list[0] への参照をタプルを作成する関数に渡します。そうすれば、関数は、新しいタプルを割り当てたり、あるタプルから別のタプルにコピーしたりすることなく、配列内の既に割り当てられているタプルの空の内容を埋めることができます。好奇心からベクトルでそれをやろうとしたところ、イテレータが 0x0 を指したときにセグ フォールトが発生したため、構文はベクトルでは機能しないと思います。では、この割り当てをすばやく行う方法はありますか?

これは、実際の使用と同じくらい言語を学ぶための質問であるため、興味深いと思われる他の接線関連のものを自由に投げ込んでください。私は学びたいと思っています。

ありがとう。

4

1 に答える 1

34

C++11 ではstd::vector::emplace_back、新しいオブジェクトをインプレースで構築する を使用できるため、このメソッドを使用するとコピーが行われません。

このメソッドを使用すると、次のことができます。

my_struct some_struct;
some_struct.tuple_list.emplace_back(1, 5, "bleh");

tupleオブジェクトに次のコンストラクターが含まれていると仮定します。

tuple::tuple(int, int, const std::string&)

編集:移動セマンティクスを使用して、事前に割り当てられたタプルを保存することもできます。

my_struct some_struct;
tuple a_tuple;
/* modify a_tuple, initialize it, whatever... */
some_struct.push_back(std::move(a_tuple)); // move it into your vector

またはtuple、ベクトルに格納された後にへの参照を使用します。

my_struct some_struct;
some_struct.tuple_list.emplace_back(1, 5, "bleh");
// store a reference to the last element(the one we've just inserted)
tuple &some_tuple = some_struct.tuple_list.back(); 
some_tuple.foo();

上記のすべてのソリューションでは、tupleコピーを回避しながら、1 つだけ作成しています。

于 2012-05-07T20:09:59.730 に答える