【问题标题】:C++ Ternary Operator Calls Copy Constructor Instead of Move Constructor [duplicate]C ++三元运算符调用复制构造函数而不是移动构造函数[重复]
【发布时间】:2021-06-25 07:33:11
【问题描述】:

我正在使用 VS Code 在 Linux 中使用 g++ 进行编译和调试。

需要的包含和使用:

#include <string>
#include <iostream>

using namespace std;

这是我的可移动班级:

class A {
public:
    A(const string& strA) : strA(strA) {}

    A(const A& a) : A(a.strA) {
    }

    A(A&& a) : A(a.strA) {
        a.strA = "";
    }

    string strA;
};

返回 A 实例的示例函数:

A RetA() {
    A a("a");
    A b("bha");

    string ex;
    cin >> ex;
    a.strA += ex;

    return ex == "123" ? a : b;
}

这是简单的主要内容:

int main() {
    A a(RetA());

    return 0;
}

RetA 函数中的返回值是复制的没有移动。为什么?

另一方面,如果我们在 RetA 函数中使用“显式 if”而不是三元运算符:

A RetA() {
    A a("a");
    A b("bha");

    string ex;
    cin >> ex;
    a.strA += ex;

    if (ex == "123")
        return a;

    return b;
}

然后它被移动没有复制。这已经是预期的行为。但奇怪的是,移动操作不适用于三元运算符。应该是这样还是 VS Code 等的错误或其他东西?

【问题讨论】:

  • 这个thread的可能副本。
  • 你确定吗?也许该对象既没有被复制也没有被移动。也许返回值优化开始了。它是强制性的,从 C++17 开始,甚至在它被允许之前。
  • 关键行:所以这里不允许复制省略,并且没有其他说明左值表达式可以假装为重载解析的右值。 - @987654322 @.

标签: c++ copy-constructor move-constructor


【解决方案1】:

return 语句中的“自动”移动是有限的:

来自Automatic move from local variables and parameters

如果表达式是一个(可能是带括号的)id 表达式,它命名一个变量,其类型是 [..]

return ex == "123" ? a : b; 不是这样。

然后正常方式完成,ex == "123" ? a : b返回一个左值,所以复制发生。

你可能会这样做

return std::move(ex == "123" ? a : b);

return ex == "123" ? std::move(a) : std::move(b);

要手动move

使用if 允许自动移动遵循上述规则

if (ex == "123")
    return a;
else
    return b;

【讨论】:

  • "返回 std::move(ex == "123" ? a : b);"效果很好。谢谢。
猜你喜欢
  • 2022-11-21
  • 1970-01-01
  • 1970-01-01
  • 2015-06-10
  • 1970-01-01
  • 2022-01-12
  • 2016-03-25
  • 2013-04-25
相关资源
最近更新 更多