STL自定义分配器

3

我正在尝试使用自定义分配器来处理STL。我尝试了下面的示例。它防止将Custom::vector指针分配给std::vector。在下面的方法中是否存在任何缺点或性能问题。

namespace Custom
{
  template <typename _Tp, typename Allocator = CustomAllocator<_Tp> >
  class vector : private std::vector<_Tp, Allocator >
  {
    using std::vector<_Tp, Allocator>::push_back;
  };
}

int main(void)
{
  Custom::vector<int> v;
  v.push_back(1);
}

2
你想达成什么目标?只是默认使用你的自定义分配器,还是试图限制可以在 v 上调用哪些方法? - Sneftel
我们想使用自定义分配器,因为我们希望分配器使用静态内存池,并且我们也想限制方法。我们想要一些向量的功能,但默认情况下仅为一些模块[而非全局范围]使用自定义分配器。 - user2331977
6
为什么不直接使用类型别名 namespace Custom { template <typename T> using vector = std::vector<T, CustomAllocator<T>>; } 呢? - MadScientist
注意:禁止将“_Tp”用作模板参数名称(对于您这个普通用户),与以下正则表达式匹配的标识符:“^ _ [A-Z] \ w *”和“\ w * __ \ w *”保留给实现在所有范围内,并且与“^ _ [a-z] \ w *”匹配的标识符保留给全局范围内的实现。 - Matthieu M.
我尝试了命名空间Custom {template <typename T> using vector = std :: vector <T,CustomAllocator <T >>; }。看起来我们需要g ++ 4.8版本的g ++; 我们使用的编译器不是4.8版本。感谢您的反馈。 - user2331977
2个回答

1

不。

分配的性能显然取决于CustomAllocator的实现。


1
鉴于您要做什么、需要兼容哪些地方、哪些不需要的信息几乎没有,几乎不可能回答这个问题。
假设使用声明在派生类型的可见(即public)部分中,这是缩小接口并设置不同分配器的一种方式。这里有不同的考虑因素,其中一个是只有在Custom::vector或friend的上下文中才能将向量用作std::vector,这意味着外部代码将无法将Custom::vector转换为std::vector>,这可能是好事或坏事。如果需要外部代码能够通过指针或引用将Custom::vector用作std::vector>,则可以使继承公开,或者删除该类型并提供类型别名(如果唯一的意图是将分配器默认为与std::allocator不同的内容)。
另一个问题,在C++分配器模型中无处不在,就是您不再拥有词汇类型。两个仅在分配器上不同的std::vector(或Custom::vector)实例化不相关,并且不能互换使用。您不能编写一个以std::vector<T> 为参数的函数,并使用std::vector<T, CA<T>> 调用它。同样,这可能或可能不是一个问题,并且可以通过到处添加模板来解决(要么使用迭代器操作,要么对分配器类型进行模板化)。
关于最后一点,有一个提议将多态分配器添加到C++标准中,并且在BSL中存在现有实现。权衡的是每个分配需要支付额外的动态调度并获得词汇类型(代码不需要模板化,bsl::vector<T>是相同类型,无论使用哪个分配器来拉取内存)。动态调度的成本大小尚待讨论(目前正在委员会讨论中)。一些初始性能测试似乎表明,动态调度的成本对于最低性能的分配器而言很小,但对于更快的(固定缓冲区,顺序)分配器而言则很明显。在选择正确的分配器时,将为您在C++模型中带来一些收益,并在BSL分配器模型中带来较小的增益(常数因子)。当分配成本较小时,常数因子更加明显。优势在于bsl::vector<T>是一个词汇类型,一个接受bsl::vector<T>的函数不在乎使用了哪个分配器,它只是可用

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接