Last updated:2026-10-12
C++ ref and reference_wrapper¶
A Deep Dive into std::cref, std::ref and std::reference_wrapper in C++¶
In C++ programming, we sometimes need to pass references around without copying, or to use constant objects where a reference is required. To address these problems, the C++ standard library provides three useful tools: std::cref, std::ref and std::reference_wrapper. This article takes a deep look at the purpose of these tools, their differences, and their practical applications.
Besides, we know that in Rust an Unwrap method is often implemented. How do we do that in C++?
That brings us to a piece of Apache Arrow code:
std::optional<std::reference_wrapper<const TransportStatusDetail>>
TransportStatusDetail::Unwrap(const Status& status) {
std::shared_ptr<StatusDetail> detail = status.detail();
if (!detail) return std::nullopt;
if (detail->type_id() != kTypeId) return std::nullopt;
return std::cref(arrow::internal::checked_cast<const TransportStatusDetail&>(*detail));
}
Afterwards we can call it like this to extract the actual TransportStatusDetail from the Status.
Below we'll look at it from several angles, and finally give the complete demo code.
1. std::cref: Creating a Reference to a Constant¶
std::cref is a template function used to create a reference to a constant object. It returns a std::reference_wrapper object that can be used wherever a reference is needed. This is particularly useful for passing function arguments, since it lets us pass constant objects without copying while preserving reference semantics.
Example:
#include <iostream>
#include <functional>
void printValue(const int& value) {
std::cout << "Value: " << value << std::endl;
}
int main() {
int number = 42;
auto crefNumber = std::cref(number);
printValue(crefNumber); // 使用常量引用传递参数
return 0;
}
2. std::ref: Creating a Modifiable Reference¶
Unlike std::cref, std::ref is a template function used to create a reference to a modifiable object. It returns a std::reference_wrapper object that can be used wherever a reference is needed, while also allowing the referenced object to be modified.
Example:
#include <iostream>
#include <functional>
void modifyValue(int& value) {
value *= 2;
}
int main() {
int number = 42;
auto refNumber = std::ref(number);
modifyValue(refNumber); // 使用可修改的引用作为参数
std::cout << "Modified Value: " << number << std::endl;
return 0;
}
3. std::reference_wrapper: A Wrapper for References¶
std::reference_wrapper is a template class used to wrap references so they can be stored in containers or passed around as references. It provides reference-like syntax and works with the standard containers, since containers cannot store references directly.
Example:
#include <iostream>
#include <vector>
#include <functional>
int main() {
int number1 = 42;
int number2 = 73;
std::vector<std::reference_wrapper<int>> numbers = {std::ref(number1), std::ref(number2)};
for (auto& num : numbers) {
num.get() += 10; // 修改原始对象的值
}
std::cout << "Number 1: " << number1 << std::endl;
std::cout << "Number 2: " << number2 << std::endl;
return 0;
}
In this example, std::reference_wrapper lets us wrap references in a container and then access and modify the original objects' values through the get() method.
4. Unwrap Demo¶
Here is the concrete code snippet; for the complete code see the content on Knowledge Planet (zhishixingqiu).
std::optional<std::reference_wrapper<const TransportStatusDetail>> Unwrap(const Status& status) {
std::shared_ptr<StatusDetail> detail = status.detail();
if (!detail) return std::nullopt;
if (detail->type_id() != kTypeId) return std::nullopt;
return std::cref(static_cast<const TransportStatusDetail&>(*detail));
}
int main() {
// 创建 TransportStatusDetail 对象
std::shared_ptr<StatusDetail> transportDetail = std::make_shared<TransportStatusDetail>();
// 创建 Status 对象并传入 TransportStatusDetail 对象
Status status(transportDetail);
auto result = Unwrap(status);
if (result) {
const TransportStatusDetail& detail = result.value().get();
// 使用 detail 进行操作
std::cout << "TransportStatusDetail found." << std::endl;
} else {
std::cout << "No valid TransportStatusDetail found." << std::endl;
}
return 0;
}
You are welcome to join the discussion of C++那些事. For more projects/content, welcome to join Knowledge Planet.
Related Topics¶
- C++ Pure Virtual Functions and Abstract Classes | C++那些事
- C++ assert | C++那些事
- C++ Bit Fields | C++那些事
- Implementing C++ Polymorphism in C | C++那些事
- C++ const Constants and Qualifiers | C++那些事
- The Complete C++ const Family | C++那些事
- C++ Dereference Operator * | C++那些事
- C++ Initialization and Assignment | C++那些事
- Ways to Return Multiple Values in C++ | C++那些事
- C++ mutable Keyword | C++那些事