gpt4 book ai didi

c++ - 使用 if 语句 move 构造函数,但使用三元运算符复制构造函数

转载 作者:行者123 更新时间:2023-11-30 05:09:35 24 4
gpt4 key购买 nike

上下文:我正在做实验以了解 gcc 何时执行 RVO ,如果不是,它什么时候使用 move 语义。我的 gcc 版本是 g++ (GCC) 4.8.5 20150623 (Red Hat 4.8.5-4)

问题:我有一个按值返回 Foo 的函数。编译器无法执行 RVO,因为有两个可能的命名返回值。当我使用三元运算符选择返回哪个 Foo 时,我需要显式调用 std::move 以避免复制。使用 if 语句时,我不需要 std::move。为什么会出现差异?

代码:

#include <iostream>

using namespace std;

struct Foo {
std::string s;
Foo() { cout << "Foo()\n"; }
~Foo() { cout << "~Foo()\n"; }
Foo(const Foo& other) : s(other.s) { cout << "Foo(const Foo&)\n"; }
Foo(Foo&& other) noexcept : s(move(other.s)) { cout << "Foo(Foo&&)\n"; }
};

Foo makeFooIf(bool which) {
Foo foo1; foo1.s = "Hello, World1!";
Foo foo2; foo2.s = "Hello, World2!";
if (which) return foo1;
else return foo2;
}

Foo makeFooTernary(bool which) {
Foo foo1; foo1.s = "Hello, World1!";
Foo foo2; foo2.s = "Hello, World2!";
return which ? foo1 : foo2;
}

Foo makeFooTernaryMove(bool which) {
Foo foo1; foo1.s = "Hello, World1!";
Foo foo2; foo2.s = "Hello, World2!";
return which ? move(foo1) : move(foo2);
}

int main()
{
cout << "----- makeFooIf -----\n";
Foo fooIf = makeFooIf(true);
cout << fooIf.s << endl;

cout << "\n----- makeFooTernary -----\n";
Foo fooTernary = makeFooTernary(true);
cout << fooTernary.s << endl;

cout << "\n----- makeFooTernaryMove -----\n";
Foo fooTernaryMove = makeFooTernaryMove(true);
cout << fooTernaryMove.s << endl;

cout << "\n----- Cleanup -----\n";
return 0;
}

输出:

----- makeFooIf -----
Foo()
Foo()
Foo(Foo&&)
~Foo()
~Foo()
Hello, World1!

----- makeFooTernary -----
Foo()
Foo()
Foo(const Foo&)
~Foo()
~Foo()
Hello, World1!

----- makeFooTernaryMove -----
Foo()
Foo()
Foo(Foo&&)
~Foo()
~Foo()
Hello, World1!

----- Cleanup -----
~Foo()
~Foo()
~Foo()

最佳答案

在某些情况下有一个隐含的举动:

§12.8.32

When the criteria for elision of a copy/move operation are met, but not for an exception-declaration, and the object to be copied is designated by an lvalue, or when the expression in a return statement is a (possibly parenthesized) id-expression that names an object with automatic storage duration declared in the body or parameter-declaration-clause of the innermost enclosing function or lambda-expression, overload resolution to select the constructor for the copy is first performed as if the object were designated by an rvalue. If the first overload resolution fails or was not performed, or if the type of the first parameter of the selected constructor is not an rvalue reference to the object’s type (possibly cv-qualified), overload resolution is performed again, considering the object as an lvalue.

我的黑体

关于c++ - 使用 if 语句 move 构造函数,但使用三元运算符复制构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46107480/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com