如果我正確地理解了這個問題(我不確定),你應該使用索引而不是指針或迭代器,因爲它是一個相對於緩衝區開始的偏移量,而不是絕對地址將被緩衝區的更改無效。
class Item
{
size_t pos; // index into the buffer
vector<int> values;
};
vector<Item> items;
// ...
std::vector<int> buffer;
buffer.resize(N);
for (auto& item : items)
{
assert(buffer.size() >= (item.pos + item.values.size()));
std::copy(std::begin(item.values), std::end(item.values),
std::begin(buffer)+item.pos);
}
這將無論是vector
或deque
的緩衝區(或任何其他與RandomAccessIterators)工作,但你似乎並不需要在緩衝區的開頭添加/移除元素(只調整它曾經並分配給現有的元素),那麼沒有理由使用矢量,這通常應該是你的容器的默認選擇,除非你需要其他容器的特定特性。
我不知道您打算如何設定Item::pos
值,也許這將是有意義:
size_t pos = 0;
for (auto& item : items)
{
item.pos = pos;
pos += item.values.size();
assert(buffer.size() >= pos);
std::copy(std::begin(item.values), std::end(item.values),
std::begin(buffer)+item.pos);
}
這將使每個項目依次進入緩衝區,並記錄在飛行的位置。
這甚至可以在不預先知道總的緩衝區大小工作,根據需要調整緩衝:
size_t pos = 0;
for (auto& item : items)
{
item.pos = pos;
pos += item.values.size();
if (buffer.size() < pos)
buf.resize(pos);
std::copy(std::begin(item.values), std::end(item.values),
std::begin(buffer)+item.pos);
}
因爲你存儲的索引,而不是一個絕對地址,它會繼續工作即使在緩衝區被調整大小並且其內容被重新定位到不同的內存塊之後。
你的意思是一樣的std ::陣列? – stonemetal 2014-10-09 20:48:05
我不認爲'的std :: array'會的工作,因爲每次迭代在我的項目,最後的緩衝區大小是已知的,但功能之間的呼叫'items'可以改變大小。我也不知道如何給每個'Item'一個指向它應該開始寫的地方的指針。 – 2014-10-09 20:51:22
'然後用指針來有項目寫入向量的某些部分如果被矢量調整創造buffer',你所設置的指針最終可能指向垃圾,因爲一個矢量的迭代器變得無效。 – PaulMcKenzie 2014-10-09 20:54:49