开发者

Creating a shared_ptr from an allocator using typedefs?

I have some code that I am retrofitting to use an alloc开发者_如何学运维ator instead of operator new and operator delete directly. One part of this code's public interface is to return not a bald pointer but a shared_ptr (being constructed from the bald pointer wandering out of new.)

I see in the public contract for an allocator several typedefs named pointer, const_reference, etc. The idea is instead of referring to types T * directly, I might use pointer, allowing an allocator author to slip in something other than a C pointer.

But I am in turn wrapping the normal pointer in a smart pointer, which wants an honest C pointer (I think.) If I attempt to change my code over to using the allocator's typedefs, will I run into trouble? I haven't tried yet (as there is a bit of leg work to do just to try) so I'm asking first..

EDIT: Here's the some of code I want to alter (I didn't include the first time, as it isn't very friendly.)

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;
}

In particular, the construct and destroy template methods called on the result of the initializer(injector) expression currently embed direct uses of new and delete. I'd like it to use the Allocator instead, and switch them to placement new / explicit destruction, to make something like

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));
  }
};

The question is, should I try to honor the allocator's typedefs? It seems like I ought to be or else I'm not using the allocator correctly (never mind that pragmatically speaking nearly all of them will have the "boring" typedef values.)

I can certainly jigger it to return Allocator::pointer instead of Impl *, up until I attempt to shove it into a shared_ptr. And maybe it just works there too? That is my question. Perhaps someone more familiar with the standard than me could say something like "So long as Allocator::pointer quacks like a operator* and you register a custom deleter, you'll be fine."

EDIT: @bdonlan raises the excellent point that a shared_ptr is templated on what would be Allocator::value_type, and not Allocator::pointer. Instead, it presumably holds a Allocator::value_type * internally. This seems to answer the question, except an allocator author might choose to implement operator Allocator::value_type * on their Allocator::pointer in such a way that, even when using the converted value, it "all works out" according to some concretely-stated semantic.

Does the standard require allocator authors to do this?

EDIT: See related.


shared_ptr (and the other TR1 smart pointers) are defined (ie, take template parameters) in terms of the element type, not the pointer type. As such, if you are using shared_ptr, you cannot substitute your own pointer representation; nor does it make sense to do so in most cases.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜