其他分享
首页 > 其他分享> > C括号/复制省略括号中的return语句

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