Going off of this question, trying to clarify if what follows is a safe / legitimate idiom to use.
In short, I have a discriminated union eg
struct var {
union {
char uchar;
shared_ptr< void > uptr;
};
};
And at some point I will need to construct uptr
in-place. My current code to construct it in-place in a copy operation (so that the reference count goes up by one, still referring to the same object as another shared_ptr
) looks like this:
void var::copy (const var & v) {
*(new ( &uptr ) decltype ( uptr )) = v.uptr;
}
The reason for this seemingly odd approach is I do need the deleter to be transferred as well. In my situation I could create another instance of the deleter since this union/variant type is a tagged sort but that seems inelegant if shared_ptr
is already up to the task.
I know for a fact from that question linked, that operator=
will copy the deleter. However will a copy-constructed shared_ptr
also copy the deleter? I assume it would, so in that case this should work, but will it maintain the same deleter for the new copy?
void var::copy (const var & v) {
new ( &uptr ) decltype ( uptr ) (v.uptr);
}
First, I realize it's trivial to ask "does the copy constructor work the same as copy-assignment" but I want to be sure of this or if there are any caveats to be mindful of (the header files are a bit 'thick' to read as-is, reference material isn't very clear on this, I can't tell for sure in short).
Furthermore unique_ptr
explicitly has a deleter type as a template parameter to the class itself while shared_ptr
does not, and again I know in theory why this is but not sure of what actually happens inside shared_ptr
and how it behaves in these situations.
Second, of the two forms assuming they both work the same way, or another if it's cleaner than either of these, which is preferred? Which is safer?
Note - the above code is not complete of course, only the relevant / functional lines are shown as the rest is tagged-union related (large condition blocks), and other union fields are not shown for brevity.
Aucun commentaire:
Enregistrer un commentaire