临时变量赋值给常引用安全吗 / Is it safe to make a const reference member to a temporary variable?

临时变量的生命周期

C++ 中的临时变量指的是那些由编译器根据需要在栈上产生的,没有名字的变量。其主要的用途主要有两类:

  • 函数的返回值
  • 类型转换时的中间变量

一般来说,C++ 中的临时变量在表达式结束之后 (full expression) 就被会销毁 / The temporary will be destroyed after the full expression.

The lifetime of the temporary bound to a const reference extends till the lifetime of const.

Demo

Segmentation_fault_demo++view raw
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <iostream>
#include <unordered_set>
#include <vector>

class A {
public:
A(const std::unordered_set<int>& const_v_in, std::unordered_set<int> v_in)
: const_set_values_(const_v_in), set_values_(v_in) {}

bool has_const_value(int ix) const {
return const_set_values_.find(ix) == const_set_values_.end();
}

bool has_value(int ix) const {
return set_values_.find(ix) == set_values_.end();
}

private:
const std::unordered_set<int>& const_set_values_;
std::unordered_set<int> set_values_;
};

int main() {
A a({0}, {0});

std::cout << " whether A instance has value " << a.has_value(0)
<< std::endl;
std::cout << " whether A instance has const value " << a.has_const_value(0)
<< std::endl;

return 0;
}

源码

源码下载

源码下载

编译

1
2
cd 文件下载目录
g++ oom_reference.cpp -o test --std=c++14

注意:因为编译器优化等原因 (我的版本是 g++ 7.5),你在本地验证时不一定会崩溃,但是这即使不崩溃,也是一个 undefined bahvior 问题,不安全。

1
2
// 查看 g++ 版本
g++ --version

One more thing

编程实践

// When one stores the reference one should also forbid rvalues: A(const std::unordered_set&&)=delete;

禁止移动构造_demo++view raw
1
A(const std::unordered_set<int>&&) = delete;

参考链接