Loading... C++中一个隐蔽的小坑: ```cpp std::pair<const ColumnPtr&, bool> unpack_if_const(const ColumnPtr& ptr) noexcept { // ... return std::make_pair(ptr, false); } ``` 以上代码有什么问题? 如果没有看出来,我们可以搞一个最小可复现实例: ```cpp std::pair<const int&, int> f(const int& arg) { return std::make_pair(arg, 1); } int main() { int a = 1; const auto& [b, _] = f(a); a = 2; std::cout << b; return 0; } ``` 运行一下,会发生什么? 我们会发现输出结果是: ```plaintext 1 ``` 说明我们没能够正确地通过`std::pair`传递`arg`的引用。其实这时候`b`捕获的是一个**临时对象的引用**。这是因为: ![image.png](https://zclll.com/usr/uploads/2023/03/971171360.png) `std::make_pair`默认不按引用捕获,而是通过`std::decay`捕获到非引用类型,从而按值传递! ![image.png](https://zclll.com/usr/uploads/2023/03/367519190.png) # 正确写法 同时,上面的信息也给出了对应的解决方案:**用引用包装器传递参数**。因此我们可以将最初的代码改写成: ```cpp std::pair<const ColumnPtr&, bool> unpack_if_const(const ColumnPtr& ptr) noexcept { // ... return std::make_pair(std::cref(ptr), false); } ``` 就能使得`std::make_pair`正确捕获引用了。 当然,`pair`的默认构造函数不会进行相似的`decay`,因此我们可以通过初始化列表去完成一样的目的: ```cpp std::pair<const ColumnPtr&, bool> unpack_if_const(const ColumnPtr& ptr) noexcept { // ... return {ptr, false}; } ``` © 允许规范转载 打赏 赞赏作者 赞 4 如果觉得我的文章对你有用,请随意赞赏