टी एल; डॉ
अतिरिक्त संदर्भों में C ++ प्रोग्राम का अर्थ बदल जाता है:
- तर्क-निर्भर नाम लुकअप को रोकना
- सूची संदर्भों में अल्पविराम ऑपरेटर को सक्षम करना
- अस्पष्ट पार्स के अस्पष्टता संकल्प
decltype
भावों में समर्पण भाव
- प्रीप्रोसेसर मैक्रो त्रुटियों को रोकना
तर्क-निर्भर नाम लुकअप को रोकना
जैसा कि मानक के अनुलग्नक ए में विस्तृत है, post-fix expression
प्रपत्र (expression)
का एक है primary expression
, लेकिन नहीं id-expression
, और इसलिए नहीं unqualified-id
। इसका अर्थ यह है कि तर्क-निर्भर नाम लुकअप को (fun)(arg)
पारंपरिक रूप की तुलना में फ़ॉर्म के फ़ंक्शन कॉल में रोका जाता है fun(arg)
।
३.४.२ तर्क-आश्रित नाम देखने के लिए [basic.lookup.argdep]
1 जब एक फ़ंक्शन कॉल में पोस्टफ़िक्स-एक्सप्रेशन (5.2.2) एक अयोग्य-आईडी है , तो अन्य नामस्थानों को सामान्य अयोग्य लुकअप (3.4.1) के दौरान नहीं माना जा सकता है और उन नेमस्पेस, नेमस्पेस-स्कोप फ्रेंड फंक्शन या फ़ंक्शन टेम्पलेट घोषणाएं (11.3) अन्यथा दिखाई नहीं दे सकती हैं। खोज के लिए ये संशोधन तर्कों के प्रकार पर निर्भर करते हैं (और टेम्पलेट टेम्पलेट तर्क के लिए, टेम्पलेट तर्क के नाम स्थान)। [ उदाहरण:
namespace N {
struct S { };
void f(S);
}
void g() {
N::S s;
f(s); // OK: calls N::f
(f)(s); // error: N::f not considered; parentheses
// prevent argument-dependent lookup
}
उदाहरण का]
सूची संदर्भों में अल्पविराम ऑपरेटर को सक्षम करना
अल्पविराम ऑपरेटर का अधिकांश सूची-जैसे संदर्भों (फ़ंक्शन और टेम्प्लेट तर्क, आरम्भक सूची आदि) में एक विशेष अर्थ है। a, (b, c), d
ऐसे संदर्भों में प्रपत्र के कोष्ठक नियमित रूप की तुलना में अल्पविराम ऑपरेटर को सक्षम कर सकते हैं a, b, c, d
जहाँ अल्पविराम लागू नहीं होता है।
5.18 कोमा ऑपरेटर [expr.comma]
2 संदर्भों में जहां अल्पविराम को एक विशेष अर्थ दिया जाता है, [उदाहरण: कार्यों की दलीलों की सूची (5.2.2) और आरंभिकों की सूची (8.5) - उदाहरण के रूप में] खंड 5 में वर्णित अल्पविराम ऑपरेटर केवल कोष्ठक में दिखाई दे सकता है। [ उदाहरण:
f(a, (t=3, t+2), c);
तीन तर्क हैं, जिनमें से दूसरे का मूल्य 5. उदाहरण है]
पार्सिंग वेर्सेस का एंबीगुएटी रिज़ॉल्यूशन
सी और इसके आर्कन फंक्शन डिक्लेरेशन सिंटैक्स के साथ बैकवर्ड कम्पेटिबिलिटी, आश्चर्यजनक पार्सिंग अस्पष्टता को जन्म दे सकती है, जिसे वेक्सिंग वेर्सेस कहा जाता है। अनिवार्य रूप से, किसी भी चीज़ को घोषणा के रूप में पार्स किया जा सकता है , भले ही एक प्रतिस्पर्धी पार्स भी लागू होगा।
६.६ एम्बिगुएटी रिज़ॉल्यूशन [stmt.ambig]
1 व्याकरण में अभिव्यक्ति-कथनों और घोषणाओं को लेकर एक अस्पष्टता है : एक कार्य-शैली स्पष्ट प्रकार के रूपांतरण (5.2.3) के साथ एक अभिव्यक्ति-कथन, जैसा कि इसके सबसे उप-उपप्रकार एक घोषणा से अप्रभेद्य हो सकता है, जहां पहला घोषणाकर्ता एक के साथ शुरू होता है ( । उन मामलों में बयान एक घोषणा है ।
.२ अस्पष्टता संकल्प [dcl.ambig.res]
1 एक फंक्शन-स्टाइल कास्ट और 6.8 में उल्लिखित घोषणा के बीच समानता से उत्पन्न अस्पष्टता भी एक घोषणा के संदर्भ में हो सकती है । उस संदर्भ में, विकल्प एक फ़ंक्शन घोषणा के बीच है, जिसमें पैरामीटर नाम के आसपास कोष्ठक के एक निरर्थक सेट और एक स्टाइल-स्टाइल के साथ ऑब्जेक्ट घोषणा को आरम्भक के रूप में रखा गया है। जैसा कि 6.8 में उल्लिखित अस्पष्टताओं के लिए है, संकल्प किसी भी निर्माण पर विचार करना है जो संभवतः एक घोषणा पत्र हो सकता है । [नोट: एक घोषणा को गैर-विचलन शैली के कलाकारों द्वारा स्पष्ट रूप से अस्वीकार किया जा सकता है, = आरंभिकता को इंगित करने के लिए या पैरामीटर नाम के आसपास निरर्थक कोष्ठक को हटाकर। ध्यान दें] [उदाहरण:
struct S {
S(int);
};
void foo(double a) {
S w(int(a)); // function declaration
S x(int()); // function declaration
S y((int)a); // object declaration
S z = int(a); // object declaration
}
उदाहरण का]
इसका सबसे प्रसिद्ध उदाहरण मोस्ट वैक्सिंग पार्स है , जिसका नाम स्कॉट मेयर्स ने अपने प्रभावी एससीएल के आइटम 6 में प्रचलित किया है :
ifstream dataFile("ints.dat");
list<int> data(istream_iterator<int>(dataFile), // warning! this doesn't do
istream_iterator<int>()); // what you think it does
यह एक फ़ंक्शन की घोषणा करता है data
, जिसका रिटर्न प्रकार है list<int>
। फ़ंक्शन डेटा दो पैरामीटर लेता है:
- पहला पैरामीटर नाम है
dataFile
। यह टाइप है istream_iterator<int>
। चारों ओर के कोष्ठक dataFile
अतिसुंदर हैं और उन्हें अनदेखा किया जाता है।
- दूसरे पैरामीटर का कोई नाम नहीं है। इसका प्रकार कुछ भी नहीं लेने और वापस लौटने के लिए सूचक है
istream_iterator<int>
।
पहले फ़ंक्शन तर्क के आसपास अतिरिक्त कोष्ठक रखने (दूसरे तर्क के आसपास कोष्ठक अवैध हैं) अस्पष्टता को हल करेगा
list<int> data((istream_iterator<int>(dataFile)), // note new parens
istream_iterator<int>()); // around first argument
// to list's constructor
C ++ 11 में ब्रेस-इनिशियलाइज़र सिंटैक्स है जो कई संदर्भों में इस तरह की पार्सिंग समस्याओं को साइड-स्टेप करने की अनुमति देता है।
भावों में समर्पण decltype
भाव
auto
प्रकार में कटौती के विपरीत , decltype
रेफ़ेक्नेसिटी (लवल्यू और रेवल्यू संदर्भ) को कम करने की अनुमति देता है। नियम decltype(e)
और decltype((e))
अभिव्यक्ति के बीच अंतर करते हैं:
7.1.6.2 सरल प्रकार विनिर्देशक [dcl.type.simple]
4 एक अभिव्यक्ति के लिए e
, द्वारा दर्शाया गयाdecltype(e)
प्रकार निम्नानुसार परिभाषित किया गया है:
- यदि e
एक अनिर्दिष्ट आईडी-एक्सप्रेशन या एक अनिर्धारित क्लास मेंबर एक्सेस (5.2.5) है, decltype(e)
तो इसके द्वारा होने वाली इकाई का प्रकार है e
। यदि ऐसी कोई इकाई नहीं है, या यदि e
ओवरलोड कार्यों का एक सेट नाम है, तो कार्यक्रम बीमार है;
- अन्यथा, अगर e
एक xvalue है, decltype(e)
है T&&
, जहां T
का प्रकार है e
;
- अन्यथा, यदि e
एक लैवल्यू है, decltype(e)
तो T&
, T
प्रकार कहां है e
;
- अन्यथा, decltype(e)
का प्रकार है e
।
डिक्लेयर स्पेसिफिक का ऑपरेंड एक अनवैलिडेटेड ऑपरेंड (क्लॉज 5) है। [ उदाहरण:
const int&& foo();
int i;
struct A { double x; };
const A* a = new A();
decltype(foo()) x1 = 0; // type is const int&&
decltype(i) x2; // type is int
decltype(a->x) x3; // type is double
decltype((a->x)) x4 = x3; // type is const double&
उदाहरण उदाहरण] [नोट: शामिल प्रकार के निर्धारण के नियम
decltype(auto)
7.1.6.4 में निर्दिष्ट हैं। ध्यान दें]
decltype(auto)
प्रारंभिक अभिव्यक्ति के आरएचएस में अतिरिक्त कोष्ठक के लिए समान अर्थ के नियम हैं । यहां C ++ FAQ और इससे संबंधित Q & A से एक उदाहरण दिया गया है
decltype(auto) look_up_a_string_1() { auto str = lookup1(); return str; } //A
decltype(auto) look_up_a_string_2() { auto str = lookup1(); return(str); } //B
पहला रिटर्न string
, दूसरा रिटर्न string &
, जो स्थानीय चर का संदर्भ है str
।
प्रीप्रोसेसर मैक्रो संबंधित त्रुटियों को रोकना
सी + + भाषा के साथ उनकी बातचीत में प्रीप्रोसेसर मैक्रोज़ के साथ सूक्ष्मताओं की एक मेजबान है, जिनमें से सबसे आम नीचे सूचीबद्ध हैं
- मैक्रो परिभाषा में किसी एक मैक्रो मापदंडों के आसपास कोष्ठकों का उपयोग
#define TIMES(A, B) (A) * (B);
क्रम में अवांछित ऑपरेटर पूर्वता से बचने के लिए (में जैसे TIMES(1 + 2, 2 + 1)
जो 9 पैदावार लेकिन चारों ओर कोष्ठकों 6 प्राप्त होते हैं (A)
और(B)
- सम्मिलित तर्कों के चारों ओर कोष्ठक का उपयोग अंदर करना:
assert((std::is_same<int, int>::value));
जो अन्यथा संकलित नहीं होगा
- शामिल हेडर में मैक्रो के विस्तार से बचाने के लिए एक फ़ंक्शन के आसपास कोष्ठक का उपयोग करना:
(min)(a, b)
(ADL को अक्षम करने के अवांछित दुष्प्रभाव के साथ)
&(C::f)
, का संचालन&
अभी भी हैC::f
, है ना?