【发布时间】:2011-02-19 19:32:36
【问题描述】:
似乎有关 C++0x 右值的主要建议是将移动构造函数和移动运算符添加到您的类中,直到编译器默认实现它们。
但是,如果您使用 VC10,等待是一种失败的策略,因为自动生成可能要到 VC10 SP1,或者在最坏的情况下,VC11 才会出现。很可能,等待的时间会以年为单位。
这就是我的问题。编写所有这些重复的代码并不好玩。而且看着很不爽。但对于那些被认为速度较慢的课程来说,这是一个很受欢迎的负担。对于数百甚至数千个较小的班级来说,情况并非如此。
::sighs:: C++0x 应该让我写less 代码,而不是更多!
然后我有了一个想法。我猜是很多人分享的。
为什么不按值传递所有内容? std::move + 复制省略不会使这几乎是最优的吗?
示例 1 - 典型的 Pre-0x 构造函数
OurClass::OurClass(const SomeClass& obj) : obj(obj) {}
SomeClass o;
OurClass(o); // single copy
OurClass(std::move(o)); // single copy
OurClass(SomeClass()); // single copy
缺点:浪费了右值的副本。
示例 2 - 推荐的 C++0x?
OurClass::OurClass(const SomeClass& obj) : obj(obj) {}
OurClass::OurClass(SomeClass&& obj) : obj(std::move(obj)) {}
SomeClass o;
OurClass(o); // single copy
OurClass(std::move(o)); // zero copies, one move
OurClass(SomeClass()); // zero copies, one move
优点:大概是最快的。
缺点:大量代码!
示例 3 - 值传递 + std::move
OurClass::OurClass(SomeClass obj) : obj(std::move(obj)) {}
SomeClass o;
OurClass(o); // single copy, one move
OurClass(std::move(o)); // zero copies, two moves
OurClass(SomeClass()); // zero copies, one move
优点: 无需额外代码。
缺点: 在案例 1 和 2 中浪费了一步. 如果SomeClass 没有移动构造函数,性能会受到很大影响。
你怎么看?它是否正确?与代码减少的好处相比,所发生的移动是否是普遍可以接受的损失?
【问题讨论】:
-
你是 not the first 想到这个 ;-)
-
@dean 如果我知道参数有一个移动构造函数,我将在我的代码中执行按值然后移动。如果我不知道,我会做重载右值引用的舞蹈。
-
@FredOverflow:我读过那篇文章。我喜欢它,但它在某些部分是错误的(“在最坏的情况下,性能不会更差”)而且对我的口味来说太理论化了——没有任何类型的测量。无论如何,我的帖子并不是要提出新的建议,而是要问一个问题:您更喜欢哪个?显然这取决于任务和人,但我对回应很感兴趣。 (顺便说一句,我现在想知道编译器是否可以消除 #3 中的额外分配。)
-
@dean 查看 cmets 中对此答案的讨论:stackoverflow.com/questions/2794369/…
-
@dean 我不认为说“在最坏的情况下,性能不会更差”是错误的。完全正确。如果以后还是要复制,可以省略,直接修改参数。我不认为该声明适用于这种复制到成员的情况,在某些情况下,性能确实会差一些。
标签: c++ c++11 move-semantics rvalue-reference