यदि मेरे पास कोई ऑब्जेक्ट a
है या तो एक अंतर्निहित सरणी या एक वर्ग-प्रकार उपयुक्त operator []
के साथ, और इसके लौटाए गए प्रकार को स्वयं अनुक्रमित किया जा सकता है, तो मुझे एक सामान्य फ़ंक्शन कैसे लिखना चाहिए जो उन सभी को एक भिन्नता के साथ इंडेक्स कर सकता है अलग ब्रैकेट ब्लॉक के बजाय कॉल करें? दूसरे शब्दों में, मैं की तरह भाव बना सकते हैं:कोई एक वैरिएडिक-आधारित जंजीर-इंडेक्सिंग फ़ंक्शन कैसे बना सकता है?
a[i0][i1]...[iK]
और मैं एक ही समारोह के रूप में यह लिखने के लिए सक्षम होना चाहते हैं:
slice(a, i0, i1, ..., iK)
सी के नियमों ++ operator []
की आवश्यकता होती है एक तर्क पर काम करने के बाद से , यह विविध पदार्थों के साथ कम अनुकूल है। (यह सवाल एक Usenet धागे पर आधारित है, जहां मैं ऐसी ही कुछ पूछ की कोशिश की है, अपने आप को सुलझाने केवल संभवतः-नेस्ट में निर्मित सरणियों समाप्त।)
एक पहला वार:
template < typename T, typename U >
constexpr
auto slice(T &&t, U &&u) noexcept(???) -> ???
{ return ce_forward<T>(t)[ ce_forward<U>(u) ]; }
template < typename T, typename U, typename V, typename ...W >
constexpr
auto slice(T &&t, U &&u, V &&v, W... &&w) noexcept(???) -> ???
{
return slice(ce_forward<T>(t)[ce_forward<U>(u)], ce_forward<V>(v),
ce_forward<W>(w)...);
}
ce_forward
समारोह टेम्पलेट्स हैं constexpr
-मार्क std::forward
। (मानक में कुछ चीजें जिन्हें constexpr
चिह्नित किया जा सकता है।) मैं रिटर्न प्रकार और अपवाद विनिर्देश स्पॉट्स में डालने के लिए सही चीजों को समझने की कोशिश कर रहा हूं। कुछ मामलों और प्रतिवाद मैं के बारे में पता कर रहे हैं:
- निर्मित
operator []
एक संकार्य की आवश्यकता है एक गणना या पूर्णांक प्रकार होने के लिए एक डाटा-सूचक (या सड़ा हुआ सरणी संदर्भ) और अन्य किया जाना है। ऑपरेंड किसी भी क्रम में हो सकता है। मुझे नहीं पता कि एक ऑपरेंड को एक क्लास-टाइप के साथ एक स्पष्ट प्रकार (गैर-स्पष्ट?) रूपांतरण के साथ एक उचित प्रकार में बदला जा सकता है या नहीं। - एक वर्ग प्रकार
operator []
को गैर स्थैतिक सदस्य फ़ंक्शन के रूप में परिभाषित कर सकता है। इस तरह के किसी भी फ़ंक्शन में केवल एक पैरामीटर हो सकता है (this
के अलावा)। - बिल्ट-इन ऑपरेटर फेंक नहीं सकता है। (जब तक ऑपरेंड यूडीटी रूपांतरण पर आधारित नहीं हो सकते हैं; कहा कि रूपांतरण एकमात्र संभावित फेंक बिंदु है।) सीमा त्रुटियों के कारण अनिर्धारित व्यवहार यहां हमारे अधिकार से परे है।
- क्या अंतिम इंडेक्सिंग कॉल एल-वैल्यू संदर्भ देता है, आर-वैल्यू संदर्भ, या मान
slice
के रिटर्न प्रकार में प्रतिबिंबित होना चाहिए। - यदि (अंतिम?) कॉल मूल्य-दर है, तो
std::is_nothrow_move_constructible<ReturnType>::value
अपवाद विनिर्देश के लिए OR'd होना चाहिए। (संदर्भ संदर्भ रिटर्नnoexcept
हैं।) - यदि अंतर्निहित ऑपरेटर में एक सरणी शामिल है, तो उस चरण के लिए लौटा संदर्भ आर-वैल्यू संदर्भ होना चाहिए यदि सरणी भी एक है। (यह एक प्रकार का दोष है क्योंकि एरे के विपरीत पॉइंटर्स, अपने लक्ष्य की एल-बनाम आर-वैल्यू स्थिति खो देते हैं, इसलिए पारंपरिक रिटर्न हमेशा एल-वैल्यू संदर्भ होगा।)
- क्लास-प्रकार इंडेक्सिंग ऑपरेटरों के लिए, सुनिश्चित करें कि अपवाद-spec और रिटर्न-प्रकार अनुभाग एक ही ओवरलोड (यदि एक से अधिक) का संदर्भ लें जो फ़ंक्शन बॉडी का उपयोग करता है। ओवरलोड के लिए सावधान रहें जो केवल
this
(const
/volatile
/दोनों/न तो और/या&
/&&
/न तो) की योग्यता में भिन्न हों।
यह 'constexpr' होना चाहिए? – kennytm
इसके लिए मैं इसका उपयोग कर रहा हूं, जब भी संभव हो, यह 'constexpr' होना चाहिए। – CTMacUser
क्या आपने बस रिटर्न प्रकार और 'अस्वीकरण' विनिर्देश दोनों के लिए 'वापसी' कथन में समान अभिव्यक्ति डालने पर विचार किया है? जैसे 'noexcept (noexcept (std :: declval() [std :: declval ()]) -> decltype (std :: declval () [std :: declval ()])। –