使用基类指针的右值引用的函数具有来自复制的派生类的指针

时间:2013-09-16 21:44:46

标签: c++ pointers rvalue-reference

这是我的意思的一个简短的例子。我发现很难简洁地说出这个问题。

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的限制。

1 个答案:

答案 0 :(得分:5)

fooA*进行了反驳。您没有给它A*,而是B*。这需要转换。形成临时 A*,绑定到右值引用,更改,最后丢弃。原始B*永远不会受到影响。