vector
:のこの架空の実装を考えてみましょう。
template<class T> // ignore the allocator
struct vector
{
typedef T* iterator;
typedef const T* const_iterator;
template<class It>
void insert(iterator where, It begin, It end)
{
...
}
...
}
問題
ここで直面する微妙な問題があります。同じベクトル内のアイテムを参照する可能
性があります。begin
end
where
たとえば、ユーザーが次のように言った場合:
vector<int> items;
for (int i = 0; i < 1000; i++)
items.push_back(i);
items.insert(items.begin(), items.end() - 2, items.end() - 1);
It
がポインタタイプでない場合は、問題ありません。
しかし、私たちは知らないので、それが[begin, end)
すでにベクトル内にある範囲を参照していないことを確認する必要があります。
しかし、これをどのように行うのでしょうか?C ++によると、同じ配列を参照していない場合、ポインターの比較は未定義になります。
そのため、コンパイラは、アイテムがエイリアスしないと誤って通知する可能性がありますが、実際にはエイリアスしているため、不要なO(n)の速度が低下します。
考えられる解決策と警告
1つの解決策は、ベクトル全体を毎回コピーし、新しいアイテムを含めてから、古いコピーを破棄することです。
ただし、上記の例のように、すでに十分な容量がある場合でも、1つのアイテムを挿入するためだけに1000のアイテムをコピーするシナリオでは、これは非常に低速です。