C括号/复制省略括号中的return语句
作者:互联网
我正在使用以下代码愚弄,并使用我的visual studio 2017应用程序和两个不同的在线编译器得到了不同的结果.在发布模式下,visual studio在两种情况下都会忽略复制/移动,而两个在线编译器只是在没有表达的返回语句的情况下执行此操作.我的问题是:谁是正确的,更重要的是什么是承保规则. (我知道您可以将括号与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
解决方法:
GCC是对的.
根据[class.copy.elision] paragraph 1:
This elision of copy/move operations, called copy elision, is permitted in the following circumstances (which may be combined to eliminate multiple copies):
in a
return
statement in a function with a class return type, when the expression is the name of a non-volatile automatic object (other than a function parameter or a variable introduced by the exception-declaration of a handler ([except.handle])) with the same type (ignoring cv-qualification) as the function return type, the copy/move operation can be omitted by constructing the automatic object directly into the function call’s return object…
return语句中的括号表达式不符合copy elision的条件.
实际上,在CWG 1597的解析之前,return语句中带括号的id-expression甚至不能被视为执行移动的右值.
标签:nrvo,copy-elision,c,language-lawyer 来源: https://codeday.me/bug/20190727/1550300.html