【问题标题】:Are member variables in temporary objects implicitly moved when possible?临时对象中的成员变量是否尽可能隐式移动?
【发布时间】:2013-05-17 14:54:45
【问题描述】:

在我的类中,我使用std::vector 等作为成员变量,它们带有自己的移动构造函数。我没有为我的类显式声明移动构造函数,并且它们大部分都没有隐式声明。

如果我的类的隐式复制构造函数或隐式赋值运算符使用右值调用,具有移动构造函数的成员是复制还是移动?

如果它们被移动,在使用具有移动可构造成员的类时,是否有任何理由避免使用临时对象?

【问题讨论】:

  • 如果使用 C++11,它们将被移动,如果使用 C++03,它们将被复制。从 C++11 开始,所有标准库容器类都将利用移动语义。
  • 但是,如果我明确声明了一个复制构造函数,情况就不是这样了吗?据我所知,将 const 引用附加到右值然后分配内容将不允许使用成员的移动赋值运算符。
  • “它们大部分没有被隐式声明。” 那么你的类型没有移动语义,所以没有办法移动成员

标签: c++ c++11 move-semantics rvalue


【解决方案1】:

如果您的类没有显式声明移动构造函数/赋值运算符并且它们也没有隐式声明,那么隐式声明的复制 ctor/assignment-op 将不会移动成员,而是复制它们。

如果为您的班级隐式声明了 move ctor/assignment-op,它们将被移动。你说他们不是——为什么?你的类有自定义析构函数吗?您应该争取一种不需要自定义 dtor、复制/移动 ctor 和复制/移动分配操作的设计 - 有时称为“零规则”。

如果您确实需要自定义 dtor,则应显式声明 move ctor/assignment-op 以使用移动语义。如果您的编译器支持它,您可以将它们声明为默认值。

【讨论】:

  • "如果您的编译器支持它,您可以将它们声明为默认值。"在大多数情况下这不是一个坏主意(五规则)吗?
  • “你说他们不是——为什么?”是的,大多数都有析构函数。
  • @DyP 有问题的类似乎隐式定义了复制 ctor,因此它要么已经损坏,要么 dtor 只执行不会影响默认移动的事情 - 例如记录某些内容。跨度>
  • 析构函数主要用于调试目的。
  • @gokturk 那么你可以将移动函数声明为默认值。
【解决方案2】:

无论是隐式创建还是显式声明,您的复制构造函数都只有一个签名,因此编译器无法根据该构造函数的右侧操作数生成不同的代码。它必须在所有情况下都复制可移动属性,因为复制构造函数只有一组代码必须适用于所有可能的输入。

我认为您的最后一个问题可能与性能有关,但我无法确定。我建议你编写最明显的代码,然后让优化器对其进行破解。然后分析结果,看看它是否表明临时创建和破坏给您带来了问题,只有当它们是,您才应该考虑替代机制。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-08
    • 1970-01-01
    相关资源
    最近更新 更多