C++ 使用NRV优化的函数应遵循哪些规则
我应该遵循哪些规则或提示来启用函数在函数中使用NRV(命名返回值)优化?我从不同的地方吸收了这些技巧,但不知道我的理解是否正确:C++ 使用NRV优化的函数应遵循哪些规则,c++,C++,我应该遵循哪些规则或提示来启用函数在函数中使用NRV(命名返回值)优化?我从不同的地方吸收了这些技巧,但不知道我的理解是否正确: 要返回的对象在函数中不应该有任何名称(那么为什么它被称为返回值优化!!) return语句的对象应该用括号括起来 要返回的对象应具有显式和内联复制构造函数 如果您指的是NRVO(命名的返回值优化)而不是RVO(返回值优化),那么对象必须在函数内部命名。否则,它将只符合RVO的资格,而不符合NRVO的资格。因此有一个很好的理由将其命名为返回值优化 请查看以下示例: RV
void foo(int x, int y, BigObject& ret)
{
ret._constructor_(x, y);
}
void bar()
{
BigObject obj; // Allocate obj on the stack, but don't construct it just yet!
foo(4, 6, obj); // Now obj is constructed by foo()
}
void foo(int x, int y, int z, BigObject& ret)
{
ret._constructor_(x, y);
// Do something with ret
ret.setZ(z);
}
void bar()
{
BigObject obj; // Allocate obj on the stack, but don't construct it just yet!
foo(4, 6, 7, obj); // Now obj is constructed by foo()
}
NRVO:
将由优化编译器转换为以下伪代码:
void foo(int x, int y, BigObject& ret)
{
ret._constructor_(x, y);
}
void bar()
{
BigObject obj; // Allocate obj on the stack, but don't construct it just yet!
foo(4, 6, obj); // Now obj is constructed by foo()
}
void foo(int x, int y, int z, BigObject& ret)
{
ret._constructor_(x, y);
// Do something with ret
ret.setZ(z);
}
void bar()
{
BigObject obj; // Allocate obj on the stack, but don't construct it just yet!
foo(4, 6, 7, obj); // Now obj is constructed by foo()
}
请注意,优化是否真正发生在很大程度上取决于编译器。一些编译器(像非常旧的编译器)根本不会执行RVO或NRVO,而其他编译器对此优化可能有不同的约束。以下是MSVC对NRVO的限制说明:
如果您指的是NRVO(命名的返回值优化)而不是RVO(返回值优化),那么对象必须在函数内部命名。否则,它将只符合RVO的资格,而不符合NRVO的资格。因此有一个很好的理由将其命名为返回值优化
请查看以下示例:
RVO:
将由优化编译器转换为以下伪代码:
void foo(int x, int y, BigObject& ret)
{
ret._constructor_(x, y);
}
void bar()
{
BigObject obj; // Allocate obj on the stack, but don't construct it just yet!
foo(4, 6, obj); // Now obj is constructed by foo()
}
void foo(int x, int y, int z, BigObject& ret)
{
ret._constructor_(x, y);
// Do something with ret
ret.setZ(z);
}
void bar()
{
BigObject obj; // Allocate obj on the stack, but don't construct it just yet!
foo(4, 6, 7, obj); // Now obj is constructed by foo()
}
NRVO:
将由优化编译器转换为以下伪代码:
void foo(int x, int y, BigObject& ret)
{
ret._constructor_(x, y);
}
void bar()
{
BigObject obj; // Allocate obj on the stack, but don't construct it just yet!
foo(4, 6, obj); // Now obj is constructed by foo()
}
void foo(int x, int y, int z, BigObject& ret)
{
ret._constructor_(x, y);
// Do something with ret
ret.setZ(z);
}
void bar()
{
BigObject obj; // Allocate obj on the stack, but don't construct it just yet!
foo(4, 6, 7, obj); // Now obj is constructed by foo()
}
请注意,优化是否真正发生在很大程度上取决于编译器。一些编译器(像非常旧的编译器)根本不会执行RVO或NRVO,而其他编译器对此优化可能有不同的约束。以下是MSVC对NRVO的限制说明:
我回答了你关于1的问题(这似乎是重点),但我并不真正理解2,我也不确定3,但我认为编译器并不关心复制构造函数是内联的和显式定义的(不过它可能不应该有显式关键字,因为如果没有优化,它需要隐式调用),但我并不真正理解2,我也不确定3,但我认为编译器并不关心复制构造函数是内联的并显式定义的(它可能不应该有explicit关键字,因为如果没有进行优化,它需要隐式调用).aaah!我错误地认为RVO是NRVONo的缩写形式。两者都是由编译器完成的,用户根本无法控制它们。当对象在返回函数中具有“本地名称”时,NRVO就会完成,而RVO是在与
return
语句在同一行上创建时完成的。aaah!我错误地认为RVO是NRVONo.Bo的缩写形式这是由编译器完成的,用户根本无法控制它们。当对象在返回函数中具有“本地名称”时,NRVO完成,当对象与return
语句在同一行上创建时,RVO完成。