これが私が言いたいことの簡単な最小限の例です。質問を簡潔に表現するのは難しいと思いました。
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
か? foo
階層または関数について変更できることに関して、外部 API によって非常に制限されています。