के विनिर्देश पर विचार रेंज आधारित पाश के के लिए शुरू-expr और अंत expr (N4140 [stmt.ranged]/p1)। एक सीमा के प्रकार _RangeT
की __range
,अनुकरण रेंज आधारित पाश के शुरू के लिए/अंत व्यवहार
शुरू-expr और अंत expr इस प्रकार निर्धारित कर रहे हैं को देखते हुए:
- अगर
_RangeT
एक सरणी प्रकार है, शुरू-expr और एंड-एक्सप्र क्रमशः__range
और__range + __bound
हैं, जहां__bound
सरणीबद्ध है। यदि_RangeT
अज्ञात आकार की एक सरणी है या अधूरा प्रकार की एक सरणी है, तो प्रोग्राम खराब है;- अगर
_RangeT
एक वर्ग प्रकार है, अयोग्य-आईडी रोंbegin
औरend
वर्ग के सदस्य पहुँच देखने (3.4.5) द्वारा के रूप में अगर वर्ग_RangeT
के दायरे में ऊपर देखा जाता है, और या तो (या दोनों) अगर पाता है कम से कम एक घोषणा, शुरू-expr और अंत expr__range.begin()
कर रहे हैं और__range.end()
क्रमश;- अन्यथा, शुरू-expr और अंत expr
begin(__range)
औरend(__range)
, क्रमशः, जहांbegin
औरend
संबद्ध नेमस्पेस (3.4.2) में देखा जाता है। [नोट: साधारण अयोग्य लुकअप (3.4.1) नहीं किया गया है। - अंत टिप्पणी]
यह साधारण सी ++ कोड में इस सटीक व्यवहार अनुकरण करने के लिए संभव है? जैसे कि, हम लिख सकते हैं एक magic_begin
और एक magic_end
समारोह टेम्पलेट ऐसी है कि
for(auto&& p : range_init) { /* statements */ }
और
{
auto&& my_range = range_init;
for(auto b = magic_begin(my_range), e = magic_end(my_range); b != e; ++b){
auto&& p = *b;
/* statements */
}
}
हमेशा ठीक उसी व्यवहार है?
गैर जवाब योग्य कॉल करने के लिए std::begin
/std::end
(अन्य बातों के अलावा तीसरी गोली, संभाल नहीं करता है) और using std::begin; begin(range);
, क्योंकि अन्य बातों के अलावा, कि अस्पष्ट है अगर begin
के लिए ADL एक अधिभार कि std::begin
के रूप में समान रूप से अच्छा है पाता शामिल ।
उदाहरण के लिए,
namespace foo {
struct A { int begin; };
struct B { using end = int; };
class C { int* begin(); int *end(); }; // inaccessible
struct D { int* begin(int); int* end();};
struct E {};
template<class T> int* begin(T&) { return nullptr; }
template<class T> int* end(T&) { return nullptr; }
}
foo::A a; foo::B b; foo::C c; foo::D d; foo::E e;
दिया मैं magic_begin(a)
/magic_begin(b)
/magic_begin(c)
/magic_begin(d)
एक संकलन त्रुटि होना चाहता हूँ, और magic_begin(e)
(int*)nullptr
वापस जाने के लिए।
आपका मतलब है, आप 'magic_end' को' b' के लिए संकलन त्रुटि होना चाहते हैं, है ना? – Columbo
@ कोल्लमबो ठीक है, अगर हम श्रेणी के लिए श्रेणी-आधारित हैं, तो दोनों त्रुटियां होंगी। लेकिन मैं "जादू_बेजिन 'में से कम से कम एक और' magic_end' के परिणामस्वरूप एक त्रुटि में खुश हूं"। –
ओह, क्षमा करें! दूसरे बुलेट बिंदु को गलत तरीके से पढ़ें। – Columbo