gpt4 book ai didi

c++ - 虚函数可以成为 RVO(返回值优化)的候选者吗?

转载 作者:可可西里 更新时间:2023-11-01 16:40:34 24 4
gpt4 key购买 nike

C++ 编译器是否能够将 RVO 应用于虚函数?

在这种情况下:

class AbstractReader
{
//...
public:
virtual std::vector<float> getFloatVector() = 0;
//...
}

class XmlReader : public AbstractReader
{
//...
public:
virtual std::vector<float> getFloatVector()
{
std::vector<float> result;

//Do some parsing here...

return result;
}
//...
}



class BinaryReader : public AbstractReader
{
//...
public:
virtual std::vector<float> getFloatVector()
{
std::vector<float> result;

//Do some decoding here...

return result;
}
//...
}

RVO 可以应用于 return result; 行吗?我猜不会。

那么,在这种情况下,std::move(result) 是返回大型容器的方法吗?

谢谢

最佳答案

是的,编译器可以执行RVO。我编写了一些测试代码并通过 godbolt 运行它:

struct M {
M();
M(const M&);
M(M &&);
~M();
double * ptr;
};

M getM();

struct A {
virtual M foo() = 0;
};

struct B : A {
virtual M foo() override;
};

M B::foo(){
M m;
return m;
}

struct C : B {
virtual M foo() override;
};
M C::foo(){
M m = getM();
return m;
}

A* getA();

int main(){
A* p = getA();
M m = p->foo();
}

g++ -O3 产生

B::foo():
pushq %rbx
movq %rdi, %rbx
call M::M()
movq %rbx, %rax
popq %rbx
ret
C::foo():
pushq %rbx
movq %rdi, %rbx
call getM()
movq %rbx, %rax
popq %rbx
ret
main:
subq $24, %rsp
call getA()
movq (%rax), %rdx
movq %rax, %rsi
movq %rsp, %rdi
call *(%rdx)
movq %rsp, %rdi
call M::~M()
xorl %eax, %eax
addq $24, %rsp
ret

反汇编中明显没有调用 M 的复制或 move 构造函数。


此外,标准中规定复制省略标准的段落没有区分虚拟成员函数和非虚拟成员函数,只要满足复制省略标准,return 语句的重载解析“首先执行,就好像对象是由右值指定的一样”。

也就是说,在一个函数中

M foo() {
M m = /*...*/;
return m;
}

如果出于某种原因无法进行复制省略,并且 move 构造函数可用,return m; 将始终调用 move 构造函数而不是复制构造函数。因此,如果您要返回局部变量,则无需使用 std::move 作为返回语句。

关于c++ - 虚函数可以成为 RVO(返回值优化)的候选者吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26279545/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com