Consider the following scenario:
using reloc_only_t = gsl::non_null<std::unique_ptr<int>>;
struct B
{
reloc_only_t _b;
};
struct D : B
{
reloc_only_t _d;
};
// B and D are forcibly relocate-only
void sink(B);
void foo(D obj)
{
sink(reloc obj); // What happens here?
}
Given the rules we established, I'd say this is ill-formed? I'm not sure of how object slicing happens behind the scene, but I guess it involves an extra copy of the base part of the object.
If we had move-only types instead, and had used std::move instead of reloc, the following would have happened in my understanding:
sink is called with an xvalue of D.
sink(B) is selected as we can move-construct B from a D xvalue.
B is constructed in sink's parameter slot, effectively leaving B's part of obj in a moved-from state, and not touching D's part.
- At the end of
foo (assuming obj is not an unowned parameter), its destructor is called.
In the general case (with relocate-only types or not), when reloc selects the relocation constructor, I would like to have a similar approach (assuming obj is not an unowned parameter):
sink is called with a prvalue of D.
sink(B) is selected as we can relocate-construct B from a D prvalue.
- The non-
B parts of obj are destructed.
B is constructed in sink's parameter slot, by relocating the B's part of obj.
obj lifetime ends before sink is called.
This would be equivalent to:
struct D : B
{
reloc_only_t _d;
B get_B(this D reloc) { return reloc B; }
};
void foo(D obj)
{
sink((reloc obj).get_B());
}
Except that it would happen automatically. I suspect it at least requires D to have no user-provided destructor.
What do you think?
Consider the following scenario:
Given the rules we established, I'd say this is ill-formed? I'm not sure of how object slicing happens behind the scene, but I guess it involves an extra copy of the base part of the object.
If we had move-only types instead, and had used
std::moveinstead ofreloc, the following would have happened in my understanding:sinkis called with an xvalue ofD.sink(B)is selected as we can move-constructBfrom aDxvalue.Bis constructed insink's parameter slot, effectively leavingB's part ofobjin a moved-from state, and not touchingD's part.foo(assumingobjis not an unowned parameter), its destructor is called.In the general case (with relocate-only types or not), when
relocselects the relocation constructor, I would like to have a similar approach (assumingobjis not an unowned parameter):sinkis called with a prvalue ofD.sink(B)is selected as we can relocate-constructBfrom aDprvalue.Bparts ofobjare destructed.Bis constructed insink's parameter slot, by relocating theB's part ofobj.objlifetime ends beforesinkis called.This would be equivalent to:
Except that it would happen automatically. I suspect it at least requires
Dto have no user-provided destructor.What do you think?