将分配器用于不同类型的结构字段
Using the allocator for a structure fields of different types
我有一个自定义分配器,它的实例共享类型为 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>
或其他东西。
我特别需要 3 个分配器(例如,如果您使用多态分配器,您可能需要为每个对象分配一个特定的分配器)。
你也可以有一个重载的构造函数,它接受一个分配器并从中构造另外三个(只有当每个分配器从其他 2 个分配器反弹时,在这种情况下或者它们是多态分配器)
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)) {}
或者您可以将问题传递给 class 的构造函数并从一个字符串和两个向量移动(或者将其保留为聚合并在使用该类型的地方使用分配器进行初始化)
我有一个自定义分配器,它的实例共享类型为 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>
或其他东西。
我特别需要 3 个分配器(例如,如果您使用多态分配器,您可能需要为每个对象分配一个特定的分配器)。
你也可以有一个重载的构造函数,它接受一个分配器并从中构造另外三个(只有当每个分配器从其他 2 个分配器反弹时,在这种情况下或者它们是多态分配器)
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)) {}
或者您可以将问题传递给 class 的构造函数并从一个字符串和两个向量移动(或者将其保留为聚合并在使用该类型的地方使用分配器进行初始化)