C++是否有类似RVO的东西用于将临时对象传递给函数
C++ Is there something like RVO for passing temporary objects to functions?
使用RVO,可以在不移动或复制的情况下从返回的对象创建对象。在将对象传递给函数时,是否可以执行类似的操作?
class SomeClass {
int a;
public:
SomeClass(int _a) {a = _a; std::cout << "createdn";}
SomeClass(const SomeClass& source) {a = source.a; std::cout << "copiedn";}
SomeClass(SomeClass&& source) {a = source.a; std::cout << "movedn";}
};
void create(SomeClass&& source) {
SomeClass some_object( std::move( source));
//p_some_object = new SomeClass( std::move( source));
//new( p_some_object) SomeClass( std::move( source));
}
// ...
create(SomeClass(15));
在本例中,结果为"创建、移动"。(GCC 5.4/C++11/-O3)与新的或放置新的相同。没有分支或任何东西,为什么不能在不移动的情况下创建它?
不能保证编译器必须进行足够的内联和分析,以识别出source
引用的临时对象是不必要的。除此之外,即使是RVO也适用于价值语义;当&&
引用开始发挥作用时,不能保证。
碰巧的是,如果你遵循C++函数参数的一般规则,GCC会很好地处理你的情况:"如果你无论如何都需要复制参数,按值接受参数。">
通过值接受意味着,在这种情况下,参数被构造为调用的一部分,不需要复制或移动(它可以,在GCC上,是"RVO"-ed)。
class SomeClass {
int a;
public:
SomeClass(int _a) {a = _a; std::cout << "createdn";}
SomeClass(const SomeClass& source) {a = source.a; std::cout << "copiedn";}
SomeClass(SomeClass&& source) {a = source.a; std::cout << "movedn";}
};
void create(SomeClass some_object) {
}
int main() {
create(SomeClass(15));
}
如果您尝试它,它只显示created
消息。
如果目标是让create
为您构建对象,那么使用带有参数转发的模板函数,以便在create
中构建它,例如
template<typename T, class... Args>
T create(Args&&... args) {
T some_object(std::forward<Args>(args)...);
return some_object;
}
int main() {
auto foo = create<SomeClass>(15);
}
它通过将构造函数参数作为转发引用传递,并在create
中构造对象本身来解决问题,避免了任何额外的构造,如图所示。
RVO不会在引用中发生,也不会在从函数参数创建另一个对象时发生。
如果您将参考参数更改为值参数,则RVO将应用于它,而不是本地对象:
void create(SomeClass source) {
SomeClass otherObject = std::move(source); // No RVO, object constructed from parameter
}
// ...
create(SomeClass{15}); // RVO applied to source parameter
然而,您可以使用lambda作为函数参数来实现它:
template<typename C>
void create(C source) {
SomeClass some_object{source()};
}
// ...
create([]{ return SomeClass{15}; });
您可以检查实时输出
相关文章:
- 在不复制临时对象的情况下延长其生存期
- 为什么当我们有常量引用时创建临时对象?
- 程序如何'remember'临时对象?
- 返回对临时对象的引用
- 防止临时对象文件访问 MSVC 中的磁盘
- 是否可以在C++中移动临时对象的属性?
- 通过引用传递临时对象
- 临时C++对象是否为左值?
- 临时对象:术语澄清
- 存储对(可能)临时对象的引用是否合法,只要引用不比对象存活?
- 临时对象有身份吗?
- 临时对象上的运算符重载
- 如何在没有 std::move 的情况下移动临时对象
- 临时对象在C++中是不可避免的吗?
- 编译错误:临时对象构造函数中缺少参数
- 为什么在按值返回时创建临时对象,而不是在按值传递给函数参数时创建临时对象
- 我试图创建临时对象的方式有错误吗
- 子表达式中临时对象的生存期
- 将非 const 对象用于 const 参数
- C++是否有类似RVO的东西用于将临时对象传递给函数