使用typedef从分配器创建shared_ptr

Creating a shared_ptr from an allocator using typedefs?

本文关键字:shared ptr 创建 分配器 typedef 使用      更新时间:2023-10-16

我有一些代码,我正在改造使用allocator而不是operator newoperator delete直接。这段代码的公共接口的一部分不是返回一个秃指针,而是返回一个shared_ptr(从偏离new的秃指针构造而来)

我在一个分配器的公共合约中看到了几个名为pointer, const_reference等的类型。我的想法是不直接引用类型T *,我可能使用pointer,允许分配器作者插入C指针以外的其他东西。

但是我反过来把普通指针包装在一个智能指针中,它需要一个诚实的C指针(我认为)。如果我试图将代码更改为使用分配器的类型定义,我会遇到麻烦吗?我还没有试过(因为有一点腿部工作要做,只是尝试),所以我先问…

EDIT:这是我想修改的一些代码(我第一次没有包括,因为它不是很友好)

template<typename Injector, typename Iface, typename Allocator, typename Impl, typename A1>
class New<Injector, Iface, Allocator, Impl, Impl(A1)>: public Binding<Injector> {
public:
  static Impl * provide(Injector const & injector) {
    SAUCE_SHARED_PTR<A1> a1(injector.template provide<A1>());
    return initializer(injector).template construct<Impl, SAUCE_SHARED_PTR<A1> >(a1);
  }
  static void dispose(Injector const & injector, Iface * iface) {
    Impl * impl = static_cast<Impl *>(iface);
    initializer(injector).destroy(impl);
  }
};
// Elsewhere
template<typename Iface>
SAUCE_SHARED_PTR<Iface> provide() const {
  Iface * provided = provideFromBinding<Iface>(
    Module::template bindings<Injector_> );
  SAUCE_SHARED_PTR<Iface> smartPointer;
  smartPointer.reset(provided, deleter);
  return smartPointer;
}

特别是,调用initializer(injector)表达式结果的constructdestroy模板方法目前直接使用了newdelete。我希望它使用Allocator代替,并将它们切换到放置新/显式销毁,以制作类似

的东西
template<typename Injector, typename Iface, typename Allocator, typename Impl, typename A1>
class New<Injector, Iface, Allocator, Impl, Impl(A1)>: public Binding<Injector> {
public:
  static Impl * provide(Injector const & injector) {
    SAUCE_SHARED_PTR<A1> a1(injector.template provide<A1>());
    Allocator allocator;
    Impl * impl = allocator.allocate(sizeof(Impl));
    initializer(injector).template construct<Impl, SAUCE_SHARED_PTR<A1> >(impl, a1);
    return impl;
  }
  static void dispose(Injector const & injector, Iface * iface) {
    Allocator allocator;
    Impl * impl = static_cast<Impl *>(iface);
    initializer(injector).destroy(impl);
    allocator.deallocate(impl, sizeof(Impl));
  }
};
问题是,我应该遵从分配器的类型定义吗?看起来我应该这样做,否则我没有正确地使用分配器(更不用说从实用的角度来说,几乎所有的分配器都有"无聊的"typedef值)

我当然可以让它返回Allocator::pointer而不是Impl *,直到我试图把它塞进shared_ptr。也许它在那里也起作用?这是我的问题。也许比我更熟悉这个标准的人会这样说:"只要Allocator::pointeroperator*一样嘎嘎叫,你注册一个自定义删除器,你就没事了。"

EDIT: @bdonlan提出了一个很好的观点,即shared_ptr被模板化为Allocator::value_type,而不是Allocator::pointer。相反,它可能在内部保存一个Allocator::value_type *。这似乎回答了这个问题,除了分配器作者可能选择在他们的Allocator::pointer上实现operator Allocator::value_type *的方式,即使使用转换后的值,它也会根据一些具体陈述的语义"全部工作"。

标准要求分配器作者这样做吗?

EDIT:参见相关内容。

shared_ptr(以及其他TR1智能指针)是根据元素类型定义的(即接受模板参数),不是指针类型。因此,如果使用shared_ptr,则不能替换自己的指针表示;在大多数情况下,这样做也没有意义。