On Sun, 27 Dec 2020 23:52:44 -0500 "Arthur O'Dwyer" <arthur.j.odwyer@gmail.com> wrote:
> [...] This part sounds like Lénárd Szolnoki's proposal for further
> constraining constructors of default_delete. I've got an
> implementation of it here:
> https://github.com/Quuxplusone/llvm-project/commit/ec526c22aa43954d35356f63b55867c16aa08e88
> and on Godbolt: https://p1144.godbolt.org/z/hEYz6c
> (Lénárd, have you written a paper for this proposal yet? Shouldn't
> you, or someone, do that?)
Yes, coming soon. Notable that there is already a "rebind" mechanism of
default_delete, its converting constructor. [...]
I would prefer this to a separate rebind mechanism
I consider there to be two separate issues here:
(1) When we talk about "rebind", we're talking about a type-level operation (FacilityType x NewElementType -> NewFacilityType). For example, std::allocator<int>::rebind<double> is an alias for std::allocator<double>, or std::shared_ptr<Foo>::rebind<Bar> is an alias for std::shared_ptr<Bar>. (I'm omitting the actual traits-class stuff you'd have to type in real life, for simplicity.)
(2) Converting constructors are the value-level counterpart (FacilityValue x NewFacilityType -> NewFacilityValue). For example, if ai is a std::allocator<int>, then std::allocator<double>(ai) is an allocator<double> with "the same value" as ai.
So in order to implement `vector<bool>` or `map<K,V>`, you need both a way to rebind the allocator type within the same "family," and appropriate converting constructors so that you can actually create instances of the rebound type once you've got it.
> [...] I suspect
> that you're going to have trouble with the fact that dynamic_cast is
> not reversible: it's quite possible to have an A *a1, dynamic_cast it
> to a B*, dynamic_cast the B* back to an A*, and end up with a
> completely different object! So if your strategy is to return a
> unique_ptr<B, SomeDeleter> with a deleter that dynamic_casts B* back
> to A* and deletes that with the original deleter... well, that's not
> going to work the way you wanted. https://godbolt.org/z/Y376Kr
I don't think that the non-reversibility of dynamic_cast is a problem
for default delete. Does it matter which A subobject of a D
complete object the pointer points to when you delete it? This seems to
be a red herring for me, but correct me if I'm wrong.
Well, it doesn't matter for deletion, if A's destructor is virtual. (And if A's destructor is non-virtual, then you probably don't want to just delete it like that.)
But it might conceivably matter for some user-defined deleter type that did more than just `delete p`.
–Arthur