1

これが私が言いたいことの簡単な最小限の例です。質問を簡潔に表現するのは難しいと思いました。

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 によって非常に制限されています。

4

1 に答える 1