4

ドラフトでは次のようなレガシーコードがあります。

// sadly I have to use this structure
struct LegacyStruct {
  int* values;
}
LegacyStruct* LgStr;
....
    std::vector<int> vec;
    // fill vector in some way here  

    size_t sz = vec.size();
    LgStr->values = new int[sz];
    std::copy(vec.begin(), vec.end(), &LgStr->values[0]);

vecは巨大になる可能性があるため、int*にコピーしないようにする必要があります。それを行う方法はありますか?私は次のことを試みました:

// type of new operator explained in More Effective C++
LgStr->values = new (&vec[0])int[vec.size()];

OK、valuesvec内部配列の先頭を指していますが、vecがスコープ外になると破棄されます。しかし、私はそれを維持する必要があります。

&vec[0] = nullptr; // does not compile of course

したがって、質問は次のとおりです。この場合、移動セマンティクスを適用することは可能ですか?または多分他のトリック?

4

2 に答える 2

6

vector簡単な答えは、いいえ、のバッファの所有権をの外部に譲渡する方法はないということvectorです。

私はあなたの最善の選択肢はvectorラッパーを使用してちょうど死なないことを確認することだと思います:

class LegacyStructWrapper : private boost::noncopyable  // Or declare private copy constructor/copy assignment or use `= delete` in C++11.
{
private:
    std::vector<int> vec_;
    LegacyStruct wrapped_;
}

その後、を使用する必要があるときはいつでもvalues、に割り当てるだけ&vec_[0]です。これは、アイテムを追加する場合/追加するまで一定に保たれますvector(したがって、ベクトルのサイズ変更によって問題が発生しないように注意する必要があります)

于 2012-06-19T14:20:47.360 に答える
4

うん、あなたはそうすることができます-小さなトリックで:

struct LegacyStruct {
  std::vector<int> backingStore;
  int* values;
  LegacyStruct(std::vector<int>& aSource) {
    // Steal memory
    aSource.swap(backingStore);
    // Set pointer
    values = &backingStore[0];
  };
}

操作はvector.swapintをコピーしません。

于 2012-06-19T14:25:44.407 に答える