विषय पर बढ़ें

अंतिम अद्यतन:2026-10-12

C++ ref और reference_wrapper

C++ के std::cref, std::ref और std::reference_wrapper की गहरी समझ

C++ प्रोग्रामिंग में कभी-कभी हमें बिना copy किए रेफ़रेंस पास करना होता है, या रेफ़रेंस चाहिए ऐसी जगह constant ऑब्जेक्ट उपयोग करना होता है। इन समस्याओं को हल करने के लिए C++ स्टैंडर्ड लाइब्रेरी तीन उपयोगी टूल देती है: std::cref, std::ref और std::reference_wrapper। यह लेख इन टूल्स के उपयोग, अंतर और व्यावहारिक एप्लिकेशन पर गहराई से चर्चा करेगा।

इसके अलावा, हम जानते हैं कि Rust भाषा में अक्सर Unwrap मेथड implement किया जाता है, C++ में इसे कैसे implement करें?

इसके लिए Apache arrow का कोड देखें, जिसमें यह हिस्सा है:

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 निकाल सकते हैं।

Status status(transportDetail);
auto result = Unwrap(status);

नीचे कुछ पहलुओं से देखते हैं, और आख़िर में पूरा Demo कोड देते हैं।

1. std::cref: constant रेफ़रेंस बनाना

std::cref एक template फ़ंक्शन है, जो constant ऑब्जेक्ट के रेफ़रेंस बनाने के लिए उपयोग होता है। यह एक std::reference_wrapper ऑब्जेक्ट लौटाता है, जिसे रेफ़रेंस चाहिए ऐसी जगह उपयोग किया जा सकता है। यह फ़ंक्शन पैरामीटर पास करने में ख़ास उपयोगी है, क्योंकि यह हमें बिना copy किए constant ऑब्जेक्ट पास करने और साथ में रेफ़रेंस की semantics बनाए रखने देता है।

उदाहरण:

#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 एक template फ़ंक्शन है, जो बदले जा सकने वाले ऑब्जेक्ट के रेफ़रेंस बनाने के लिए उपयोग होता है। यह एक std::reference_wrapper ऑब्जेक्ट लौटाता है, जो हमें रेफ़रेंस चाहिए ऐसी जगह उपयोग करने देता है, और साथ में refer किए गए ऑब्जेक्ट को बदलने की अनुमति देता है।

उदाहरण:

#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: रेफ़रेंस का wrapper

std::reference_wrapper एक template क्लास है, जो रेफ़रेंस को wrap करती है, ताकि उसे कंटेनर में स्टोर किया जा सके या रेफ़रेंस के रूप में पास किया जा सके। यह रेफ़रेंस जैसा syntax देती है और स्टैंडर्ड कंटेनरों के साथ उपयोग हो सकती है, क्योंकि कंटेनर सीधे रेफ़रेंस स्टोर नहीं कर सकते।

उदाहरण:

#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 हमें रेफ़रेंस को कंटेनर में wrap करने देता है, और फिर get() मेथड से मूल ऑब्जेक्ट की वैल्यू एक्सेस और बदली जा सकती है।

4.Unwrap Demo

यहाँविशिष्ट कोड सेगमेंट दिया गया है, पूरा कोड Knowledge Planet की सामग्री में देखें।

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;
}

आइए साथ मिलकर C++那些事 पर चर्चा करें, ज़्यादा प्रोजेक्ट्स/सामग्री के लिए Knowledge Planet में शामिल हों।

संबंधित विषय

टिप्पणियाँ