Использование распределителя для структуры полей разных типов - PullRequest
0 голосов
/ 06 марта 2020

У меня есть собственный распределитель, экземпляры которого разделяют буфер памяти типа TrivialSpace:

class TrivialSpace
{
public:
    uint8_t * Allocate(std::size_t memory_size)
    {
        ...
        return ptr_to_mem;
    }
...
};

template <class T>
class TrivialAllocator
{
public:

    using value_type = T;

    TrivialAllocator(TrivialSpace & space) : m_space(space)
    {
    }

    template <class Q>
    TrivialAllocator(const TrivialAllocator<Q> & other) : m_space(other.m_space)
    {
    }

    T * allocate(std::size_t n)
    {
        return reinterpret_cast<T*>(m_space.Allocate(n * sizeof(T)));
    }

    void deallocate(T* p, std::size_t n)
    {
    }

private:

    TrivialSpace & m_space;

    template <class Q>
    friend class TestAllocator;
};

и структуру, содержащую std::string и std::vector:

using String = std::basic_string<char, std::char_traits<char>, TrivialAllocator<char>>;

template <class T>
using Vector = std::vector<T, TrivialAllocator<T>>;

struct A
{
    String a;
    Vector<int> b;
    Vector<String> c;
};

1) Как правильно создать экземпляр структуры A my TrivialAllocator?

2) И как заставить код работать с TrivialAllocator и std::allocator? Когда типы полей определены, как указано выше или следующим образом (в зависимости от некоторых #ifdef, вероятно):

using String = std::string;

template <class T>
using Vector = std::vector<T>;

Моя идея состояла в том, чтобы передать экземпляр Allocator конструктору структуры, но это не так Ясно, какую специализацию Allocator я должен пройти - Allocator<char>, Allocator<int> или что-то еще.

1 Ответ

1 голос
/ 06 марта 2020

Я бы специально взял 3 распределителя (например, если вы использовали полиморф c, вам может потребоваться указать c один для каждого объекта).

Вы также можете иметь перегруженный конструктор который берет один распределитель и строит остальные три из него (только если каждый распределитель отскочил от других 2, которые в этом случае или с распределителем полиморфи c они)

    A(Allocator<char> a_alloc, Allocator<int> b_alloc, Allocator<String> c_alloc) : a(a_alloc), b(b_alloc), c(c_alloc) {}

    template<class Alloc,
    std::enable_if_t<
        std::is_same_v<std::allocator_traits<Alloc>::template rebind_alloc<char>, Allocator<char>> &&
        // Next 2 maybe redundant based on what you are doing
        std::is_same_v<std::allocator_traits<Alloc>::template rebind_alloc<int>, Allocator<int>> &&
        std::is_same_v<std::allocator_traits<Alloc>::template rebind_alloc<String>, Allocator<String>>,
    int> = 0>
    A(Alloc alloc) : A(Allocator<char>(alloc), Allocator<int>(alloc), Allocator<String>(alloc)) {}

Или вы могли бы передать проблему конструктору класса и перейти от строки и двух векторов (или оставить ее как агрегат и инициализировать с помощью распределителей, где используется тип)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...