右值引用是否与左值引用具有相同的开销?

Tay*_*ols 6 c++ overhead c++11 pass-by-rvalue-reference

考虑这个例子:

#include <utility>

// runtime dominated by argument passing
template <class T>
void foo(T t) {}

int main() {
    int i(0);
    foo<int>(i); // fast -- int is scalar type
    foo<int&>(i); // slow -- lvalue reference overhead
    foo<int&&>(std::move(i)); // ???
}
Run Code Online (Sandbox Code Playgroud)

foo<int&&>(i)foo<int>(i),还是涉及指针开销foo<int&>(i)

编辑:作为建议,跑步g++ -S给了我同样51管路组件文件foo<int>(i)foo<int&>(i),但foo<int&&>(std::move(i))导致71行的汇编代码(它看起来像差异的来源std::move).

编辑:感谢那些推荐g++ -S不同优化级别的人 - 使用-O3(和制作foo noinline)我能够获得看起来像xaxxon解决方案的输出.

xax*_*xon 5

在您的具体情况下,它们可能都是一样的.来自godbolt与gcc -O3的结果代码是https://godbolt.org/g/XQJ3Z4:

#include <utility>

// runtime dominated by argument passing
template <class T>
int foo(T t) { return t;}

int main() {
    int i{0};
    volatile int j;
    j = foo<int>(i); // fast -- int is scalar type
    j = foo<int&>(i); // slow -- lvalue reference overhead
    j = foo<int&&>(std::move(i)); // ???
}
Run Code Online (Sandbox Code Playgroud)

是:

    mov     dword ptr [rsp - 4], 0 // foo<int>(i);
    mov     dword ptr [rsp - 4], 0 // foo<int&>(i);
    mov     dword ptr [rsp - 4], 0 // foo<int&&>(std::move(i)); 
    xor     eax, eax
    ret
Run Code Online (Sandbox Code Playgroud)

volatile int j是这样编译器不能优化了所有的代码,因为它本来知道调用的结果被丢弃,整个程序将优化不了了之.

但是,如果你强制函数不被内联,那么事情会有所改变int __attribute__ ((noinline)) foo(T t) { return t;}:

int foo<int>(int):                           # @int foo<int>(int)
        mov     eax, edi
        ret
int foo<int&>(int&):                          # @int foo<int&>(int&)
        mov     eax, dword ptr [rdi]
        ret
int foo<int&&>(int&&):                          # @int foo<int&&>(int&&)
        mov     eax, dword ptr [rdi]
        ret
Run Code Online (Sandbox Code Playgroud)

上面:https://godbolt.org/g/pbZ1BT

对于这样的问题,请学习爱https://godbolt.orghttps://quick-bench.com/(快速工作台要求您学习如何正确使用谷歌测试)


Oli*_*liv 5

参数传递的效率取决于ABI.

例如,在Linux上,Itanium C++ ABI指定将引用作为指向引用对象的指针传递:

3.1.2参考参数

通过将指针传递给实际参数来处理引用参数.

这与参考类别(rvalue /左值参考)无关.

从更广泛的角度来看,我在丹麦技术大学的一份文件中找到了这个引用,该文件称为大会,它分析了大多数编译器:

在所有方面,引用被视为与指针相同.

因此,rvalue和左值引用涉及所有ABI上的指针开销.