前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >深入理解 C++ 中的 std::cref、std::ref 和 std::reference_wrapper

深入理解 C++ 中的 std::cref、std::ref 和 std::reference_wrapper

作者头像
公众号guangcity
发布2023-09-02 10:44:24
5690
发布2023-09-02 10:44:24
举报
文章被收录于专栏:光城(guangcity)光城(guangcity)

深入理解 C++ 中的 std::cref、std::ref 和 std::reference_wrapper

在 C++ 编程中,有时候我们需要在不进行拷贝的情况下传递引用,或者在需要引用的地方使用常量对象。为了解决这些问题,C++ 标准库提供了三个有用的工具:std::crefstd::refstd::reference_wrapper。这篇文章将深入探讨这些工具的用途、区别以及实际应用。

此外,我们知道Rust语言中,经常实现了Unwrap方法,在C++中如何实现?

这就参考Apache arrow的代码了,有这么一段:

代码语言:javascript
复制
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));
}

随后我们便可以通过这样调用,提取出Status中实际的TransportStatusDetail。

代码语言:javascript
复制
Status status(transportDetail);
auto result = Unwrap(status);

下面来从几个方面看看,最后给出整个Demo代码。

1. std::cref:创建常量引用

std::cref 是一个模板函数,用于创建对常量对象的引用。它返回一个 std::reference_wrapper 对象,可以在需要引用的地方使用。这在函数参数传递中特别有用,因为它允许我们在不进行拷贝的情况下传递常量对象,同时保持引用的语义。

示例:

代码语言:javascript
复制
#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:创建可修改的引用

std::cref 不同,std::ref 是一个模板函数,用于创建对可修改对象的引用。它返回一个 std::reference_wrapper 对象,允许我们在需要引用的地方使用,同时允许修改被引用的对象。

示例:

代码语言:javascript
复制
#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:引用的包装器

std::reference_wrapper 是一个模板类,用于包装引用,使其能够在容器中存储或以引用的形式传递。它提供类似引用的语法,并且可以与标准容器一起使用,因为容器无法直接存储引用。

示例:

代码语言:javascript
复制
#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;
}

在这个示例中,std::reference_wrapper 允许我们将引用包装在容器中,然后通过 get() 方法来访问和修改原始对象的值。

4.Unwrap Demo

这里给出具体的代码段,其完整代码参见知识星球内容。

代码语言:javascript
复制
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;
}
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2023-08-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 光城 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 深入理解 C++ 中的 std::cref、std::ref 和 std::reference_wrapper
    • 1. std::cref:创建常量引用
      • 2. std::ref:创建可修改的引用
        • 3. std::reference_wrapper:引用的包装器
        • 4.Unwrap Demo
        相关产品与服务
        容器服务
        腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档