我在玩弄下面的代码,使用我的 Visual Studio 2017 应用程序和两个不同的在线编译器得到了不同的结果。在发布模式下,Visual Studio 确实在这两种情况下都省略了复制/移动,而两个在线编译器只是在没有括号的 return 语句的情况下这样做。我的问题是:谁是对的,更重要的是,基本规则是什么。(我知道您可以将括号与decltype(auto)
语法结合使用。但这不是当前的用例)。
示例代码:
#include <iostream>
#include <cstdio>
struct Foo
{
Foo() { std::cout << "default constructor" << std::endl; }
Foo(const Foo& rhs) { std::cout << "copy constructor" << std::endl; }
Foo(Foo&& rhs) { std::cout << "move constructor" << std::endl; }
Foo& operator=(const Foo& rhs) { std::cout << "copy assignment" << std::endl; return *this; }
Foo& operator=(Foo&& rhs) { std::cout << "move assignment" << std::endl; return *this; }
};
Foo foo_normal()
{
Foo a{};
return a;
}
Foo foo_parentheses()
{
Foo a{};
return (a);
}
int main()
{
auto a = foo_normal();
auto b = foo_parentheses();
std::getchar();
}
在线编译器1: http ://cpp.sh/75bux
在线编译器 2: http ://coliru.stacked-crooked.com/a/c266852b9e1712f3
Visual Studio 在发布模式下的输出是:
default constructor
default constructor
在另外两个编译器中,输出为:
default constructor
default constructor
move constructor