关于自定义分配器和 stl 的模板声明、别名和专用化的说明
Clarification in template declaration, alias and specialization in regards to custom allocators and stl
很抱歉标题含糊不清,但我不知道哪个是正确的术语(即使可以执行以下操作)。
假设我在某处有一个模板类(分配器):
template<class Arena, typename T> Allocator
{
public:
Allocator(Arena a);
...
};
然后我还有另一个类,它与Allocator
有某种关系,但不能专门化实例化T
参数。这个想法是为它声明一个"非专用别名",并让专用化在其他地方。像这样:
class MemoryArena
{
using Allocator<T> = AnAllocatorStrategy<T>; //not legal, but just to give the idea
void* Allocate(size_t);
};
用法应如下所示:
Arena anArena(...);
Arena::Allocator<int> allocInt; // some way declare a specialization of the alias
std::vector<int, Arena::Allocator<int>> myVec(allocInt);
这背后的主要思想是,由于stl
容器需要对所包含元素的类型进行专门的分配器,我仍然可以使用相同的内存领域,并让专用实例将分配调用转发给它。但我仍然希望竞技场本身控制基础分配策略(最终也参数化不完全专业化的AllocatorStrategy
)。
对此有什么提示吗?这可能吗?
编辑
多亏了评论,我以这种方式使用别名模板修复了声明:
class MemoryArena
{
template<typename T> using MyAllocatorTemplate = Allocator<MemoryArena, T>;;
void* Allocate(size_t);
};
我仍然需要弄清楚是否可以在不完全指定T
参数的情况下Allocator
成为MemoryArena
定义的一部分。像这样:
template<class AllocatorType<MemoryArena,?> = DefaultAllocType<MemoryArena,?>> //is possible not to specify T on MemoryArena definition?
class MemoryArena<AllocatorType>
{
template<typename T> using MyAllocatorTemplate = AllocatorType<MemoryArena,T>;
或者,欢迎任何其他建议。主要目标是让用户指定竞技场的分配器类型,但 T
参数除外(仅适用于在容器内使用分配器)。
template<template<class...>class Z, class...T0s>
struct partial_apply {
template<class...T1s>
using result = Z<T0s...,T1s...>;
};
template<template<class...>class A, template<class...>class B>
struct same_template : std::false_type {};
template<template<class...>class A>
struct same_template<A,A> : std::true_type {};
template<class...>class Default {};
template<
template<class...>class AllocatorType=Default
>
class MemoryArena {
template<class T>
using MyAllocatorTemplate = std::conditional_t<
same_template<AllocatorType, Default>{},
DefaultAllocType<MemoryArena, T>,
AllocatorType<T>
>;
};
假设除了 DefaultAllocType
之外还有其他一些 alloc 类型,OtherAllocType<Chicken, T>
。 然后:
template<class...Ts>
using OtherAllocChicken = partial_apply<OtherAllocType, Chicken>::template result<Ts...>;
using ChickenArena = MemoryArena< OtherAllocChicken >;
另一方面,如果您要求传递给传入模板的参数有时MemoryArena
本身,事情会变得更加复杂。
在参数化MemoryArena
之前,该类型不存在。 所以你必须有某种占位符,可以告诉你应该在哪里注入它。
如果您希望它始终MemoryArena
,那么事情会更容易:您已经有了该解决方案:
template<template<class...>class AllocatorType = DefaultAllocType>
class MemoryArena {
template<typename T>
using MyAllocatorTemplate = AllocatorType<MemoryArena,T>;
};
相关文章:
- .cpp和.h文件中的模板专用化声明
- 部分定义/别名模板模板参数
- 调用专用模板时出错"no matching function for call to [...]"
- 如何在C++20中创建模板别名的推导指南
- 模板专用化(按容器):value_type
- MSVC:带函数的"error C2244: unable to match function definition to an existing declaration"是指专用模板类的类型别名
- 为什么模板别名专用化取决于引用它的上下文
- 如何检查函数中的模板参数是否与给定类型别名的专用化匹配
- 如何使用类模板专用化创建别名模板的专用化
- 类模板专用化中的成员变量别名
- 模板别名可以用于部分专用化吗
- C++11中一个专用模板的名称别名
- 别名模板专用化问题
- 别名模板、部分专用化和无效参数类型无效
- 如何为模板专用化设置别名
- 专用模板是命名空间别名实际上是一个别名
- 专用类中的模板别名
- 使用完全专用的别名进行实现切换
- 函数模板专用化的别名
- 关于自定义分配器和 stl 的模板声明、别名和专用化的说明