这是我的意思的一个快速的最小示例。我发现很难简洁地表达这个问题。
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;
}
我希望这会打印
null
null
但它会打印
null
not null
快速查看 x86 反汇编会显示发生了不需要的复制,仅针对以下B*
情况:
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
在不更改签名的情况下有什么解决方案foo
吗?我非常受外部 API 的限制,无法更改层次结构或foo
函数。