परिचय
ISOC ++ 11 (आधिकारिक तौर पर ISO / IEC 14882: 2011) C ++ प्रोग्रामिंग भाषा के मानक का सबसे हाल का संस्करण है। उदाहरण के लिए, इसमें कुछ नई सुविधाएँ और अवधारणाएँ शामिल हैं:
- संदर्भों को देखें
- xvalue, glvalue, prvalue अभिव्यक्ति मूल्य श्रेणियां
- शब्दार्थ चाल
यदि हम नई अभिव्यक्ति मूल्य श्रेणियों की अवधारणाओं को समझना चाहते हैं, तो हमें इस बात से अवगत होना होगा कि वहाँ व्याप्तता और अंतराल के संदर्भ हैं। यह जानना बेहतर है कि प्रतिद्वंद्वियों को नॉन-कास्ट रैवल्यू संदर्भों में पारित किया जा सकता है।
int& r_i=7; // compile error
int&& rr_i=7; // OK
अगर हम वर्किंग ड्राफ्ट N3337 (प्रकाशित ISOC ++ 11 मानक के लिए सबसे समान ड्राफ्ट) से लेवेल्यूज़ और रिवैल्यूज़ शीर्षक वाली उपधारा को उद्धृत करते हैं, तो हम मूल्य श्रेणियों की अवधारणाओं का कुछ अंतर्ज्ञान प्राप्त कर सकते हैं।
३.१० अंतराल और अंतराल [बेसिक.लव]
1 चित्र 1 में वर्गीकरण के अनुसार वर्गीकृत किया गया है।
- एक लवल्यू (तथाकथित रूप से, ऐतिहासिक रूप से, क्योंकि लेवेल्यू बायीं ओर एक असाइनमेंट एक्सप्रेशन के रूप में प्रकट हो सकता है) एक फ़ंक्शन या ऑब्जेक्ट को नामित करता है। [उदाहरण: यदि E पॉइंटर प्रकार की अभिव्यक्ति है, तो * E एक लैवल्यू एक्सप्रेशन है, जो उस ऑब्जेक्ट या फ़ंक्शन को संदर्भित करता है, जिसमें E इंगित करता है। एक अन्य उदाहरण के रूप में, एक फ़ंक्शन को कॉल करने का परिणाम जिसका वापसी प्रकार एक लैवल्यू संदर्भ है एक लैवल्यू है। उदाहरण का]
- एक xvalue ("ईएक्सपायरिंग" मूल्य) भी एक वस्तु को संदर्भित करता है, आमतौर पर अपने जीवनकाल के अंत में (ताकि इसके संसाधनों को ले जाया जा सके, उदाहरण के लिए)। एक xvalue कुछ विशेष प्रकार के भावों का परिणाम है, जिसमें rvalue सन्दर्भ (8.3.2) शामिल हैं। [उदाहरण: एक फ़ंक्शन को कॉल करने का परिणाम जिसका वापसी प्रकार एक रैवल्यू संदर्भ है, एक xvalue है। उदाहरण का]
- एक ग्लव्यू ("सामान्यीकृत" लैवल्यू) एक लैवल्यू या एक एक्सवल्यू है।
- एक rvalue (तथाकथित, ऐतिहासिक रूप से, क्योंकि rvalues एक असाइनमेंट एक्सप्रेशन के दाईं ओर दिखाई दे सकता है) एक xvalue, एक
अस्थायी ऑब्जेक्ट (12.2) या इसके अधीन सबऑब्जेक्ट , या मान जो
किसी ऑब्जेक्ट से संबद्ध नहीं है ।
- एक प्रचलन ("शुद्ध" अवतरण) एक प्रचलन है जो एक xvalue नहीं है। [उदाहरण: एक फ़ंक्शन को कॉल करने का परिणाम जिसका वापसी प्रकार एक
संदर्भ नहीं है एक प्रचलन है। शाब्दिक का मान जैसे कि 12, 7.3e5, या
सत्य भी एक प्रचलन है। उदाहरण का]
हर अभिव्यक्ति इस वर्गीकरण में मौलिक वर्गीकरणों में से एक है: लवल्यू, ज़वल्यू, या प्रील्यूव। किसी अभिव्यक्ति की इस संपत्ति को उसकी मूल्य श्रेणी कहा जाता है।
लेकिन मैं इस बारे में बिल्कुल निश्चित नहीं हूं कि यह उपधारा अवधारणाओं को स्पष्ट रूप से समझने के लिए पर्याप्त है, क्योंकि "आमतौर पर" वास्तव में सामान्य नहीं है, "अपने जीवनकाल के अंत के पास" वास्तव में ठोस नहीं है, "व्याप्त संदर्भों को शामिल करना" वास्तव में स्पष्ट नहीं है, और "उदाहरण: एक फ़ंक्शन को कॉल करने का परिणाम जिसका वापसी प्रकार एक रव्यू संदर्भ है, एक xvalue है।" लगता है जैसे सांप अपनी पूंछ काट रहा हो।
प्राथमिक मूल्य श्रेणियों
प्रत्येक अभिव्यक्ति ठीक एक प्राथमिक मूल्य श्रेणी से संबंधित है। ये मान श्रेणियां lvalue, xvalue और prvalue श्रेणियां हैं।
lvalues
E की अभिव्यक्ति Lvalue श्रेणी से है, यदि केवल और यदि E एक ऐसी इकाई को संदर्भित करता है, जिसमें ALREADY की पहचान (पता, नाम या उपनाम) है, जो इसे E के बाहर सुलभ बनाता है।
#include <iostream>
int i=7;
const int& f(){
return i;
}
int main()
{
std::cout<<&"www"<<std::endl; // The expression "www" in this row is an lvalue expression, because string literals are arrays and every array has an address.
i; // The expression i in this row is an lvalue expression, because it refers to the same entity ...
i; // ... as the entity the expression i in this row refers to.
int* p_i=new int(7);
*p_i; // The expression *p_i in this row is an lvalue expression, because it refers to the same entity ...
*p_i; // ... as the entity the expression *p_i in this row refers to.
const int& r_I=7;
r_I; // The expression r_I in this row is an lvalue expression, because it refers to the same entity ...
r_I; // ... as the entity the expression r_I in this row refers to.
f(); // The expression f() in this row is an lvalue expression, because it refers to the same entity ...
i; // ... as the entity the expression f() in this row refers to.
return 0;
}
XValues
अभिव्यक्ति ई xvalue श्रेणी का है यदि और केवल यदि यह है
- किसी फ़ंक्शन को कॉल करने का परिणाम, चाहे वह स्पष्ट रूप से हो या स्पष्ट रूप से, जिसका वापसी प्रकार किसी वस्तु के लौटाए गए प्रकार का संदर्भ है, या
int&& f(){
return 3;
}
int main()
{
f(); // The expression f() belongs to the xvalue category, because f() return type is an rvalue reference to object type.
return 0;
}
- वस्तु प्रकार, या के लिए एक संदर्भ के लिए एक डाली
int main()
{
static_cast<int&&>(7); // The expression static_cast<int&&>(7) belongs to the xvalue category, because it is a cast to an rvalue reference to object type.
std::move(7); // std::move(7) is equivalent to static_cast<int&&>(7).
return 0;
}
- एक क्लास मेंबर एक्सेस एक्सप्रेशन जिसमें नॉन-रेफरेंस डेटा नॉन-रेफरेंस टाइप का एक मेंबर आब्जेक्ट होता है जिसमें ऑब्जेक्ट एक्सप्रेशन, या
struct As
{
int i;
};
As&& f(){
return As();
}
int main()
{
f().i; // The expression f().i belongs to the xvalue category, because As::i is a non-static data member of non-reference type, and the subexpression f() belongs to the xvlaue category.
return 0;
}
- एक पॉइंटर-टू-मेंबर एक्सप्रेशन जिसमें पहला ऑपरेंड एक ज़वल्यू है और दूसरा ऑपरेंड डेटा मेंबर का पॉइंटर है।
ध्यान दें कि ऊपर दिए गए नियमों का प्रभाव यह है कि वस्तुओं के नाम के संदर्भों को अंतराल के रूप में माना जाता है और वस्तुओं के लिए अनाम संदर्भों को xvalues के रूप में माना जाता है; कार्यों के संदर्भों के संदर्भों को नाम के रूप में माना जाता है या नहीं।
#include <functional>
struct As
{
int i;
};
As&& f(){
return As();
}
int main()
{
f(); // The expression f() belongs to the xvalue category, because it refers to an unnamed rvalue reference to object.
As&& rr_a=As();
rr_a; // The expression rr_a belongs to the lvalue category, because it refers to a named rvalue reference to object.
std::ref(f); // The expression std::ref(f) belongs to the lvalue category, because it refers to an rvalue reference to function.
return 0;
}
prvalues
अभिव्यक्ति E का संबंध प्रवल्यू श्रेणी से है यदि और केवल यदि ई न तो लैवल्यू से संबंधित है और न ही एक्सवल्यू श्रेणी से।
struct As
{
void f(){
this; // The expression this is a prvalue expression. Note, that the expression this is not a variable.
}
};
As f(){
return As();
}
int main()
{
f(); // The expression f() belongs to the prvalue category, because it belongs neither to the lvalue nor to the xvalue category.
return 0;
}
मिश्रित मूल्य श्रेणियों
दो और महत्वपूर्ण मिश्रित मूल्य श्रेणियां हैं। ये मूल्य श्रेणियां रूवेल्यू और ग्लव्यू श्रेणियां हैं।
rvalues
अभिव्यक्ति E का संबंध प्रतिद्वंद्वियों की श्रेणी से है, यदि और केवल यदि ई xvalue श्रेणी से संबंधित है, या प्रचलन वर्ग से संबंधित है।
ध्यान दें कि इस परिभाषा का अर्थ है कि अभिव्यक्ति ई का संबंध प्रतिद्वंद्वियों की श्रेणी से है, यदि और केवल तभी ई का तात्पर्य उस इकाई से है जिसकी कोई पहचान नहीं है, जो इसे ई वाईईटी के बाहर सुलभ बनाती है।
glvalues
अभिव्यक्ति E का संबंध ग्वालियर श्रेणी से है, यदि और केवल यदि ई का संबंध लैवल्यू श्रेणी से है, या xvalue श्रेणी से है।
एक व्यावहारिक नियम
स्कॉट मेयर ने अंतराल से अंतराल को अलग करने के लिए अंगूठे का एक बहुत ही उपयोगी नियम प्रकाशित किया है।
- यदि आप एक अभिव्यक्ति का पता ले सकते हैं, तो अभिव्यक्ति एक अंतराल है।
- यदि एक अभिव्यक्ति का प्रकार एक लवल्यू संदर्भ (जैसे, टीएंड या कास्ट टी एंड आदि) है, तो वह अभिव्यक्ति एक लवल्यू है।
- अन्यथा, अभिव्यक्ति एक प्रतिद्वंद्विता है। वैचारिक रूप से (और आमतौर पर वास्तव में भी), प्रतिद्वंद्विता अस्थायी वस्तुओं के अनुरूप होती है, जैसे कि फ़ंक्शंस से लौटे या निहितार्थ रूपांतरण के माध्यम से बनाई गई। अधिकांश शाब्दिक मूल्य (जैसे, 10 और 5.3) भी व्याप्त हैं।