C++11 在C++;,如何预测是否会调用移动或复制语义? 给定C++编译器在实例化临时对象时的纬度,以及调用返回值优化等机制,如果调用或复制语义将被调用(或多少),则不总是清楚的。

C++11 在C++;,如何预测是否会调用移动或复制语义? 给定C++编译器在实例化临时对象时的纬度,以及调用返回值优化等机制,如果调用或复制语义将被调用(或多少),则不总是清楚的。,c++11,move-constructor,move-assignment-operator,C++11,Move Constructor,Move Assignment Operator,几乎感觉这些原语的存在是为了附带的优化。也就是说,你可能得到,也可能得不到。当很难控制移动本身的调用时,似乎很难设计任何一种利用移动的资源管理策略 有没有一种方法可以清楚地(简单地)预测某些代码中可能发生的复制和移动的位置和数量?理想情况下,不需要是编译器内部的专家就可以做到这一点 当很难控制移动本身的调用时,似乎很难设计任何一种利用移动的资源管理策略 我会在这里反驳。在设计资源处理类时利用移动语义应该独立于客户端代码中复制或移动构造的方式或时间。一旦存在移动/分配,就可以设计客户端代码来利用这

几乎感觉这些原语的存在是为了附带的优化。也就是说,你可能得到,也可能得不到。当很难控制移动本身的调用时,似乎很难设计任何一种利用移动的资源管理策略

有没有一种方法可以清楚地(简单地)预测某些代码中可能发生的复制和移动的位置和数量?理想情况下,不需要是编译器内部的专家就可以做到这一点

当很难控制移动本身的调用时,似乎很难设计任何一种利用移动的资源管理策略

我会在这里反驳。在设计资源处理类时利用移动语义应该独立于客户端代码中复制或移动构造的方式或时间。一旦存在移动/分配,就可以设计客户端代码来利用这些特殊成员函数的存在

有没有一种方法可以清楚地(简单地)预测某些代码中可能发生的复制和移动的位置和数量

这里简单的意思有点难说,但我是这样理解的:

  • 假设一个类没有move-ctor/assignment操作符,您将始终获得一个副本。这很简单,但在处理具有用户定义的析构函数和/或复制构造函数/赋值的遗留代码中的类时,必须记住这一点,因为在这种情况下编译器不会生成移动构造函数/赋值

  • 返回值优化。这个问题被标记为C++11,因此您不能保证使用C++17带来的PRValue进行初始化时的复制省略。然而,可以公平地假设编译器已经实现了相同的机制。因此,

    struct A {};
    
    A func() { return A{}; }
    
    可以假定构造
    A
    的实例,函数返回值在调用端绑定到该实例。这既不会导致移动也不会导致复制构造。如果返回的对象有一个名称,只要
    func()
    没有导致NRVO不可能的分支,则可以乐观地假设相同的行为

    作为本指南的一个例外,同样是函数参数的函数返回值不符合返回值优化条件。因此,在移动可构造的情况下,移动/转发它们以防止复制:

    A func(A& a) { return std::move(a); }
    
    因此,将构造由
    func(A&)
    的返回值创建的对象

  • 函数参数本身并不显示它们的行为,它取决于类型及其特殊成员函数。给定

    void f1(A a1) { A a2{std::move(a1)}; };
    void f2(A& a1) { /* Same as above. */ };
    void f1(A&& a1) { /* Again, same. */ };
    
    如果
    A
    有一个move-ctor,则实例
    a2
    是move-constructed,否则,它是copy


除了上面的示例性案例之外,还有很多有待发现的地方,我无法深入了解更多细节,这也不符合答案所要求的简单性。此外,如果您不知道正在处理的类型,例如在函数模板或类模板中,则情况会有所不同。在这种情况下,Eff中的第29项很好地说明了如何处理复制或移动的相关不确定性。现代C++(假设移动操作不存在,不便宜,不使用)。但如果方向是“假设移动操作不存在、不便宜、不使用”,那就等于说在设计中不能依赖移动语义。没有?你说得对,这篇引文的上下文有点缺失。我将尝试改进对该项的引用。小挑剔:“(命名)返回值优化。问题标记为C++11,因此您不保证C++17带来的复制省略”可能建议C++17在您提到的所有情况下都保证这种优化,而它仅适用于未命名的临时变量(和匹配类型)。所以基本上只有返回语句操作数。Rest仍然在编译器的权限内。我的意思是,这只是一个明确的澄清。@luk32你是对的,谢谢你的提示。我将尝试加强对C++17副本省略的引用。