Pertanyaan Pindahkan std :: vector ke T *


semua Saya memiliki kode warisan yang dalam draf melakukan sesuatu seperti ini:

// 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 bisa sangat besar dan saya harus menghindari menyalinnya ke int *. Apakah ada cara untuk melakukannya? Saya mencoba mengikuti:

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

Baik, values menunjuk ke awal vec inner array, tetapi hancur ketika vec berada di luar ruang lingkup. Tapi aku harus menyimpannya ..

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

Jadi pertanyaannya adalah: apakah mungkin untuk menerapkan semantik gerakan dalam kasus ini? Atau mungkin beberapa trik lain?


4
2018-06-19 13:56


asal


Jawaban:


Jawaban singkatnya adalah tidak, tidak ada cara untuk mentransfer kepemilikan vectorPenyangga di luar vector.

Saya pikir pilihan terbaik Anda adalah memastikan bahwa vector hanya tidak mati dengan menggunakan pembungkus:

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_;
}

Lalu kapan saja Anda perlu menggunakannya values, tetapkan saja &vec_[0]. Ini akan tetap konstan jika / sampai Anda menambahkan lebih banyak item ke vector (jadi kamu akan harus berhati-hati untuk memastikan bahwa vektor mengubah ukuran tidak menimbulkan masalah).


5
2018-06-19 14:20



Yup, Anda dapat melakukannya - dengan trik kecil:

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

Itu vector.swap operasi tidak menyalin int.


4
2018-06-19 14:25