私は Howard Hinnant の素晴らしく小さなアリーナベースのアロケータ、short_allocを使用しています。
アリーナを超えてヒープに割り当てられているベクトルからの移動割り当ては、通常の高速な移動割り当て (つまり、ターゲットのリソースの取得) を使用して実行できることに気づきました。ただし、そうではありません。
typedef arena<16> arena_type;
typedef short_alloc<int, 16> alloc_type;
typedef std::vector<int, alloc_type> vec_type;
arena_type arena1, arena2;
vec_type vec1(alloc_type(arena1)), vec2(alloc_type(arena2));
vec1.resize(100);
void* data = vec1.data();
vec2 = std::move(vec1);
assert(vec2.data() == data); // fails
この回答で説明されているように、これはベクトルの移動代入演算子が 2 つのアロケーターを比較するためです ( is であることに注意してくださいpropagate_on_container_move_assignment
) std::false_type
。2 つのアロケーターは (アリーナが異なるため) 等しくないため、ターゲット ベクターはメモリを割り当て、値を 1 つずつ移動する必要があります。
等値演算子を
template <class T1, size_t N1, class T2, size_t N2>
bool operator==(const short_alloc<T1, N1>& x, const short_alloc<T2, N2>& y) noexcept
{
return N1 == N2 && (&x.a_ == &y.a_ || y.a_.on_heap());
}
whereon_heap()
は、アロケーターがそのアリーナを使用していないかどうかを確認します。
この解決策はかなりハックに見えます (たとえば、平等は対称ではないことに注意してください)。エレガントなソリューションはありますか?