【问题标题】:A code which seems wrong being compiled (about object return)编译似乎错误的代码(关于对象返回)
【发布时间】:2014-06-13 14:39:37
【问题描述】:

最近有人问我一个关于构造函数返回值的问题。经过几次讨论后,我发现似乎有些不对劲。这是示例:

#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)...但它看起来不对。

问题是:即使触发了任何复制推断条件,似乎也没有理由让'A(const A &)'被忽略,不是吗?

【问题讨论】:

  • A(A &amp;&amp;) 构造函数在这种情况下是可以的。为什么你认为不是?
  • 我刚刚编辑了帖子。 'temp' 是一个左值,所以我认为应该调用 'A(const A &)'。
  • 但是它正在被返回,所以你可以把它看作是调用方的右值。

标签: c++ return-value-optimization


【解决方案1】:

12.8 [class.copy]

32 - 当满足或将满足复制操作的省略条件时,除了源对象是函数参数,并且要复制的对象由左值指定时,重载决议选择首先执行副本的构造函数,就好像对象是由右值指定的一样。 [...]

NRVO 允许复制省略,因此 temp 被视为右值。

【讨论】:

  • temp首先被视为右值,如果失败,作为左值,不是吗?
猜你喜欢
  • 2019-11-24
  • 2018-08-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-23
  • 1970-01-01
  • 2023-03-14
相关资源
最近更新 更多