将std :: vector <t>移动到T * </t>

时间:2012-06-19 13:56:28

标签: c++ stl vector c++11 move-semantics

所有 我有一个遗留代码,在草案中做了类似的事情:

// 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()];

好的,values指向vec内部数组的开头,但是当vec超出范围时它会被破坏。但是我必须保留它...

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

所以问题是:在这种情况下是否可以应用移动语义? 或者其他一些技巧?

2 个答案:

答案 0 :(得分:5)

简短的回答是,不,没有办法将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添加更多项目,这将保持不变(因此必须谨慎使用以确保向量调整大小不会导致问题。)

答案 1 :(得分: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.swap操作不会复制整数。