foo
takes a refence to an A*
. You don't give it an A*
, but instead a B*
. This necessitates a conversion. A temporary A*
is formed, bound to the rvalue reference, changed, and finally discarded. The original B*
is never affected.
Function taking rvalue reference of a base class pointer is having pointers from derived classes copied
-
28-06-2022 - |
سؤال
Here's a quick minimal example of what I mean. I found it hard to succinctly phrase the question.
struct A {};
struct B : public A {};
void foo(A*&& ap)
{
ap = nullptr;
}
int main()
{
B b;
A* ap = &b;
foo(std::move(ap));
std::cout << (ap == nullptr ? "null" : "not null") << std::endl;
B* bp = &b;
foo(std::move(bp));
std::cout << (bp == nullptr ? "null" : "not null") << std::endl;
}
I hoped this would print
null
null
but instead it prints
null
not null
A quick look at the x86 disassembly shows the unwanted copying occurring, only for the B*
case:
lea eax,[bp]
push eax
call std::move<B * &> (03E14BFh)
add esp,4
mov ecx,dword ptr [eax] << Unwanted copy
mov dword ptr [ebp-0ECh],ecx << occurs here
lea edx,[ebp-0ECh]
push edx
call foo (03E14B5h)
add esp,4
Is there any solution to this without changing the signature of foo
? I'm very constrained by an external API as to what I can change about the hierarchy or the foo
function.
المحلول
لا تنتمي إلى StackOverflow