2
  • 背景:

我注意到 std::max 的签名是:

模板<typename T>
const T& max(const T&, const T&);

我想知道返回对 const T 的引用的含义...

如果我们传入两个 L 值,那么我们可以返回对这两个值之一的引用是有意义的。但是如果我们传入两个 PR 值,返回的是什么,使用它是否安全?

问题:

我与一些同事交谈,这里是这个问题的一个最小的工作示例:http: //cpp.sh/4en4

#include <iostream>
int glob = 100;
class temp{
  int* val;
public:
  temp(int n = 0){
    val = new int(n);
  }
  void print() const{ std::cout << "I store " << *val << std::endl; }
  ~temp(){
    std::cout << "temp object died" << std::endl;
    delete val;
    val = &glob;
  }
};
const temp& foo(const temp& a){
  return a;    
}

int main(){
  const temp& b = foo(2); 
  std::cout << "Is it safe?" << std::endl;
  b.print(); 
}

没有优化:

临时对象死亡
安全吗?
我存了100

适度:

临时对象死亡
安全吗?
我存储-1992206527

使用不同级别的优化运行它会产生不同的结果。但是,在所有情况下,返回引用似乎都不会延长本地对象的生命周期。它的析构函数仍然被调用,尽管在一种情况下我们似乎恢复了对被破坏对象的引用,而在另一种情况下,我们似乎有一个悬空指针。

标准:

引用 C++ 标准,文档编号 N4618:

12.2 第 6 项:

...当引用绑定到临时。引用绑定到的临时对象或引用绑定到的子对象的完整对象的临时对象在引用的生命周期内持续存在,但以下情况除外:
(6.1) — 在函数调用中绑定到引用参数的临时对象(5.2.2) 一直持续到包含调用的完整表达式完成。
(6.2) — 在函数返回语句 (6.6.3) 中临时绑定到返回值的生命周期没有延长;临时在 return 语句中的完整表达式结束时被销毁。”

从 (6.1) 开始,对于初始化 b 的整个语句,似乎应该存在一个临时的 foo(2)。

从 (6.2) 开始,似乎本地 'a' 被破坏了,这实际上破坏了临时 foo(2),导致 b 具有破坏值。

我的问题:

1a。什么是包含由 foo(2)in生成的临时的完整表达式const temp& b = foo(2);

1b。第二个 const 引用可以延长临时对象的生命周期吗?

  1. 考虑到明显的危险,为什么要这样实现 std::max ?
4

0 回答 0