c++ क्या यह std:: Ref व्यवहार तार्किक है?




c++11 (3)

इस कोड पर विचार करें:

#include <iostream>
#include <functional>

int xx = 7;

template<class T>
void f1(T arg)
{
    arg += xx;
}

template<class T>
void f2(T arg)
{
    arg = xx;
}

int main()
{
    int j;

    j=100;
    f1(std::ref(j));
    std::cout << j << std::endl;

    j=100;
    f2(std::ref(j));
    std::cout << j << std::endl;
}

निष्पादित होने पर, यह कोड आउटपुट करता है

107
100

मुझे 100 के बजाय दूसरा मान 7 होने की उम्मीद होगी।

मैं क्या खो रहा हूँ?


arg = xx;

स्थानीय arg अब xx साथ (जैसा बांधता है पढ़ें) को संदर्भित करता है। (और कोई और अधिक j लिए संदर्भित करता है)

arg += xx;

operator T& () operator += operator T& () operator += के तर्क से मेल खाने के लिए लागू किया जाता है operator += और इसलिए इसके अलावा संदर्भित ऑब्जेक्ट यानी j पर किया जाता है।

तो देखा गया व्यवहार सही है।


f2 एक छोटा संशोधन सुराग प्रदान करता है:

template<class T>
void f2(T arg)
{
    arg.get() = xx;
}

यह अब वही करता है जो आप उम्मीद करते हैं।

ऐसा इसलिए हुआ है क्योंकि std::ref रिटर्न a std::reference_wrapper<> ऑब्जेक्ट। असाइनमेंट ऑपरेटर जिसके आवरण को पुन: बनाता है। (देखें http://en.cppreference.com/w/cpp/utility/functional/reference_wrapper/operator%3D )

यह लिपटे संदर्भ के लिए एक असाइनमेंट नहीं करता है।

f1 मामले में, आप सभी के अनुसार काम कर रहे हैं क्योंकि एक std::reference_wrapper<T> T& रूपांतरण ऑपरेटर प्रदान करता है, जो int s निहित operator+ दाहिने हाथ की ओर बंधेगा।


reference_wrapper में operator = और एक गैर-स्पष्ट निर्माता है, documentation देखें।

इसलिए, भले ही यह आश्चर्यजनक हो, यह सामान्य व्यवहार है:

f2 ने xx स्थानीय रेफरेंस_वाटर को रिबोर किया।







ref