12

私は 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()は、アロケーターがそのアリーナを使用していないかどうかを確認します。

この解決策はかなりハックに見えます (たとえば、平等は対称ではないことに注意してください)。エレガントなソリューションはありますか?

4

1 に答える 1