0

I need a template class which:

  1. Manages an object through a pointer to keep the owning class as small as possible
  2. Provides move/copy/assigment operations, so that I do not need to implement them in the class.

I have thought about:

  • std::unique_ptr but this cannot be copied, 2 is not satisfied
  • An array of size 1, but it will generally manage the object directly as a member, so 1 is not satisfied
  • A vector of size 1 could work, but it might be optimized for small size in some implementations, thus not satisfying 1 either

I know how to implement this, but is there really nothing in the standard library for doing this? I'd prefer avoiding reinventing the wheel...

Thanks!

galinette
  • 8,896
  • 2
  • 36
  • 87
  • Note that while `std::string` can use the small buffer optimization, `std::vector` is prohibited from doing so. but while it can serve as internal implementation, you still need encapsulation to deal with adding or removing mappings. And it would be difficult to implement copy-on-write (after all it's all about optimization). – Cheers and hth. - Alf May 27 '14 at 14:04
  • An interesting answer is in http://stackoverflow.com/questions/13912310/how-to-approach-copying-objects-with-smart-pointers-as-class-attributes – galinette Jun 06 '14 at 06:59
  • Yep, the good robot's answer appears solid, for the problem of a smart pointer that clones. But this extra layer of indirection and dynamic allocation may itself use memory, which is what you want to save for the empty maps. Probably only *measurements* on typical usage pattern can tell. – Cheers and hth. - Alf Jun 06 '14 at 08:18

1 Answers1

2

With a reasonable interpretation of what you write, std::shared_ptr seems to be what you're asking for.

With an unreasonable interpretation, just use the object directly instead of a smart pointer. For dynamic allocation of a data member does not save memory overall. On the contrary, it has both some memory overhead and some execution time overhead.

Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331
  • std::shared_ptr will share the object pointed to, which is not what I want. I want true copy – galinette May 27 '14 at 13:47
  • The object stored directly is in this case an unordered_map wich is empty in most cases, and which is currently too big. I want to optimize out all (frequent) cases where it's empty by storing a null pointer instead of an empty hash. – galinette May 27 '14 at 13:49
  • you would need a really large number of empty maps to offset the overhead of dynamic allocation. but if so, if it's not just premature optimization, then one way to go about it is to write a wrapper class for the map. e.g. the wrapper will have to allocate a proper map when an association is added to a currently empty map. and of course, deal with copying and moving. `boost::intrusive_ptr` might be handy. – Cheers and hth. - Alf May 27 '14 at 14:00
  • 1
    @galinette an `std::unordered_map` is ALREADY a small to medium object (the size of five pointers in clang's libc++, six in gcc's libstdc++), no matter how much data the map holds. And it's already copy/move-constructible/assignable without any hassle. Rule of zero rules. :D – Massa May 27 '14 at 14:51
  • @Massa : "small" is not a precise way of thinking... 10 million of allocated objects from the class, times the class size (about 200 bytes) make it 2GB, and any reduction 40 bytes gain is welcome. – galinette May 27 '14 at 20:20
  • Keep in mind that some implementations of `shared_ptr` take as much space as four pointers, and that even a single extra heap allocation can take that much as overhead (usually more)... so, even if your object takes as much extra space, it may very well be worth it. More so if you consider cache locality issues! – Massa May 27 '14 at 20:26
  • shared_ptr is too complex and goes beyond what I need. If the owner is copied, the managed object should be copied too (No sharing) – galinette Jun 05 '14 at 16:04