सी ++ 11 के अनुसार जीसीसी bar
पर पहले दो कॉल के लिए प्रकार को कम नहीं कर सकता है। यह चेतावनी देता है क्योंकि यह एक्सटेंशन को C++ 11 में लागू करता है।
स्टैंडर्ड का कहना है कि एक समारोह टेम्पलेट के लिए एक कॉल में एक समारोह तर्क एक { ... }
है और पैरामीटर नहीं initializer_list<X>
(वैकल्पिक रूप से एक संदर्भ पैरामीटर), कि तब पैरामीटर के प्रकार {...}
से नहीं लगाया जा सकता है जब। यदि पैरामीटर इस तरह के एक initializer_list<X>
है, तो प्रारंभकर्ता सूची के तत्वों X
के खिलाफ की तुलना द्वारा स्वतंत्र रूप से निष्कर्ष निकाला जाता है, और तत्वों की कटौती की प्रत्येक मैच के लिए की है।
template<typename T>
void f(initializer_list<T>);
int main() {
f({1, 2}); // OK
f({1, {2}}); // OK
f({{1}, {2}}); // NOT OK
f({1, 2.0}); // NOT OK
}
इस उदाहरण में, पहले ठीक है, और दूसरा ठीक है भी, क्योंकि पहला तत्व पैदावार int
टाइप करें, और दूसरा तत्व {2}
T
के खिलाफ तुलना - इस कटौती एक constradiction उपज नहीं कर सकते हैं के बाद से यह नहीं है कुछ भी कम करें, इसलिए अंततः दूसरी कॉल T
int
के रूप में लेती है। तीसरा किसी भी तत्व द्वारा T
को घटा नहीं सकता है, इसलिए ठीक नहीं है। अंतिम कॉल दो तत्वों के लिए कटौती के विपरीत विरोधाभास पैदा करता है। बेहतर ब्रेसिज़ आसपास के लोगों (...)
को दूर - यह काम करने के लिए
एक तरह से मैं नोट करना चाहिए कि std::initializer_list<U>({...})
कर खतरनाक है
template <class T> void bar(std::initializer_list<std::initializer_list<T>> x) {
// ...
}
पैरामीटर प्रकार के रूप में इस तरह के एक प्रकार का उपयोग करने के लिए है। आपके मामले में यह दुर्घटना से काम करते हैं, लेकिन पर विचार
std::initializer_list<int> v({1, 2, 3});
// oops, now 'v' contains dangling pointers - the backing data array is dead!
कारण यह है कि ({1, 2, 3})
यह एक अस्थायी initializer_list<int>
{1, 2, 3}
के साथ जुड़े गुजर initializer_list<int>
की कॉपी/कदम निर्माता कहता है होता है। तब प्रारंभिक वस्तु समाप्त हो जाएगी और प्रारंभ होने पर मर जाएगा। जब कि अस्थायी उद्देश्य यह है कि सूची के साथ जुड़ा हुआ है मर जाता है, समर्थन-अप सरणी डेटा पकड़े भी नष्ट कर दिया जाएगा (अगर इस कदम elided है, यह के रूप में "वी" जब तक रहना होगा, कि बुरा है, क्योंकि यह भी व्यवहार नहीं होता खराब गारंटी!)। कोष्ठक को छोड़ते हुए रखकर v
सीधे सूची के साथ जुड़ा हुआ है, और समर्थन सरणी डेटा नष्ट हो जाता है केवल जब v
नष्ट हो जाता है।
संभावित डुप्लिकेट [मेरा टेम्पलेट प्रारंभिक सूची क्यों स्वीकार नहीं करता है] (http://stackoverflow.com/questions/4757614/why-doesnt-my-template-accept-an-initializer-list) - वह प्रश्न मूल रूप से एक डुप्लिकेट है। तथ्य यह है कि प्रारंभिक सूची में कटौती टाइप किया जा रहा है एक जी ++ एक्सटेंशन है। – Omnifarious
@Onnifarious यह सुनिश्चित नहीं है कि ये डुप्ली हैं या नहीं। मेरा सवाल स्पष्ट रूप से इस सवाल से कम विवरण मांगना था। –