当我在C++中将临时int变量赋值给const引用时会发生什么?

6

可能是重复问题:
const引用是否会延长临时变量的生命周期?

假设我有一个函数f

int f(int x){return x;}

const int &a=f(1);

我知道f(1)只是一个临时对象,在此语句执行后它将被销毁,但是:
  1. 如果将引用声明为const,会延长f(1)的生命周期吗?
  2. 如果是,那么f(1)将存储在哪里?
  3. 这是否意味着当x超出范围时它也没有被销毁?
  4. f(1)x之间有什么区别?

你需要一本好的 C++ 书籍。请见 https://dev59.com/_3RC5IYBdhLWcg3wK9yV。 - Ben Voigt
4
很少(甚至好的)书籍涵盖了这个话题。 - Konrad Rudolph
@Konrad:也许他是在指最后一个问题... - Niklas B.
@NiklasB。我不确定我是否能完全理解所有的差异。但这仍然是一个不错的非初学者问题。 - Konrad Rudolph
@KonradRudolph,我不理解的是f(1)如何返回值,因为它是一个表达式,那么它将返回一个值给f(1),这是否意味着它会像创建一个名为f(1)的新变量int一样,就像这样:int f(1)=1; - AlexDan
2个回答

8
您正在混淆表达式和值。
1)表达式f(1)返回的临时值的生命周期将被延长。这个规则对于const引用是独特的。
2)编译器可以在任何地方,但可能在堆栈上。
3)也许。这取决于编译器是否复制了x或执行了复制省略。由于类型是int,所以无关紧要。
4)有很多区别。其中一个是int f(int)内部的局部变量的名称。它是一个左值。另一个是调用int f(int)并评估为右值的表达式。

1
我知道表达式会返回值,但这些值在 f(1) 中是如何存储的?编译器是否只是像这样将 f(1) 分配为 1:int f(1)=1; 还是其他什么方式? - AlexDan

3

将临时变量绑定到const&会将临时变量的生命周期延长到引用的生命周期。


如果它延长了临时变量的生命周期,那么 f(1) 存储在哪里?它是否有自己的地址并且可以像普通变量一样被更改? - AlexDan
@AbdessamadBond 是否可以像普通变量一样更改是一个未决问题(我认为);您需要使用const_cast才能更改它,即使这样,结果可能是未定义的行为。(我认为意图是让它们成为未定义的行为,但我远非确定要求这样的措辞是否实际出现在标准中。) - James Kanze
@JamesKanze 唯一可能由 const_cast 引起未定义行为的情况是对象已被声明为 const。就我所知,对于临时对象来说,这种情况从未发生过。 - pmr
1
@pmr 这是通常的情况(非类类型的右值不带cv限定符)。我知道曾经有意图将此规则扩展到绑定到引用的临时对象上;我不知道这个意图最终如何。 (如果您有一个 void f(int const&),并使用 f(3) 调用它,则会出现问题。编译器是否需要每次创建一个新的临时对象?还是可以假设临时对象 3 没有更改?) - James Kanze

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接