C++ 编译时出现错误的代码(关于对象返回)
最近有人问我一个关于函数返回值构造的问题。经过几次讨论,我发现有些事情似乎不对劲。以下是示例:C++ 编译时出现错误的代码(关于对象返回),c++,return-value-optimization,C++,Return Value Optimization,最近有人问我一个关于函数返回值构造的问题。经过几次讨论,我发现有些事情似乎不对劲。以下是示例: #include <conio.h> #include <stdio.h> #include <iostream> /* struct A // Won't be compiled { A(void) {}; A(const A &) {}; A(A &&) = delete; }; */ struct A //
#include <conio.h>
#include <stdio.h>
#include <iostream>
/*
struct A // Won't be compiled
{
A(void) {};
A(const A &) {};
A(A &&) = delete;
};
*/
struct A // Compiled but...
{
A(void) {};
A(const A &) = delete;
A(A &&) {};
};
A func(void)
{
A temp;
return temp;// 'temp' is a named object, so it should be a lvalue and the A(const A &) should have been invoked.
//return std::move(temp); // OK.
}
int main(void)
{
func();
_getch();
return(0);
}
它将由VC或gcc编译。。。但这看起来是错的
问题是:即使触发了任何复制推断条件,似乎也没有理由忽略“acost A&”,不是吗?12.8[class.copy]:
32-当满足或将满足省略复制操作的条件时,除非源对象是函数参数,并且要复制的对象由左值指定,否则首先执行重载解析以选择复制的构造函数,就像对象由右值指定一样。[……]
NRVO允许复制省略,因此temp被视为右值。12.8[class.copy]:
32-当满足或将满足省略复制操作的条件时,除非源对象是函数参数,并且要复制的对象由左值指定,否则首先执行重载解析以选择复制的构造函数,就像对象由右值指定一样。[……]
NRVO允许拷贝省略,因此temp被视为右值。在这种情况下,AA&构造函数是可以的。为什么你不这么认为?我刚刚编辑了这篇文章。“temp”是一个左值,因此我认为应该调用“acost a&”。但它正在返回,因此您可以将其视为调用方的右值。在这种情况下,AA&&构造函数是可以的。为什么你不这么认为?我刚刚编辑了这篇文章。“temp”是一个左值,所以我认为应该调用“Aconst a&”。但是它正在被返回,所以你可以把它看作调用者端的一个右值。temp首先被视为一个右值,如果它失败了,是不是作为一个左值?temp首先被视为一个右值,如果失败了,是不是作为一个左值?