2013-07-10 5 views
14

मैं समझता हूँ कि, एक braced प्रारंभकर्ता दिया, autostd::initializer_list का एक प्रकार अनुमान है, जबकि टेम्पलेट प्रकार कटौती असफल हो जायेगी:ब्रेक किए गए प्रारंभकर्ताओं के लिए ऑटो और टेम्पलेट प्रकार की कटौती क्यों भिन्न होती है?

auto var = { 1, 2, 3 }; // type deduced as std::initializer_list<int> 

template<class T> void f(T parameter); 

f({ 1, 2, 3 });   // doesn't compile; type deduction fails 

मैं भी, जहां इस सी ++ 11 मानक में निर्दिष्ट किया जाता पता: 14.8। 2.5/5 गोली 5:

[It's a non-deduced context if the program has] A function parameter for which the associated argument is an initializer list (8.5.4) but the parameter does not have std::initializer_list or reference to possibly cv-qualified std::initializer_list type. [ Example:

template void g(T);

g({1,2,3}); // error: no argument deduced for T

end example ]

मुझे क्या पता या समझ में नहीं आता कारण है कि प्रकार कटौती व्यवहार में इस अंतर मौजूद है। सी ++ 14 सीडी में विनिर्देश सी ++ 11 जैसा ही है, इसलिए संभवतः मानकीकरण समिति सी ++ 11 व्यवहार को दोष के रूप में नहीं देखती है।

क्या कोई जानता है कि क्यों auto ब्रेसिड प्रारंभकर्ता के लिए एक प्रकार काट देता है, लेकिन टेम्पलेट्स की अनुमति नहीं है? फॉर्म के सट्टा स्पष्टीकरण "यह कारण हो सकता है" दिलचस्प है, मैं विशेष रूप से उन लोगों से स्पष्टीकरण में रूचि रखता हूं जो जानते हैं मानक क्यों लिखा गया था।

+0

हाल ही में एक और एसओ सवाल पूछा गया था जिसे आपने समझ लिया था। इसमें कुछ क्यों हो सकता है। – chris

+2

ठीक है, इसे मिला। एकमात्र असली चर्चा क्यों एक टिप्पणी है, लेकिन आप एक नज़र डाल सकते हैं: http://stackoverflow.com/questions/17496268/type-inference-with-rvalue-initializer-list – chris

+3

[स्कॉट मेयर्स] से उद्धरण (http://scottmeyers.blogspot.cz/2013/07/when-decltype-meets-auto.html): "* मुझे नहीं पता कि' ऑटो 'के लिए कटौती क्यों टाइप करें और टेम्पलेट्स के लिए समान नहीं है। अगर आपको पता है, तो कृपया मुझे बताएं! * "। –

उत्तर

0

सबसे पहले यह "फ़ॉर्म की सट्टा स्पष्टीकरण" है क्योंकि यह आपको कॉल करने के कारण "" हो सकता है।

{1,2,3} न केवल std::initializer_list<int> है बल्कि कन्स्ट्रक्टर के बिना प्रारंभिक प्रकारों को भी अनुमति देता है। उदाहरण के लिए:

#include <initializer_list> 

struct x{ 
    int a,b,c; 
}; 

void f(x){ 

} 
int main() { 
    f({1,2,3}); 
} 

सही कोड है। दिखाने के लिए कि यह जाने initializer_list के लिए निम्न कोड दिखाई नहीं दे रहा है:

#include <initializer_list> 

struct x{int a,b,c;}; 

void f(x){ 

} 
int main() { 
    auto il = {1, 2, 3}; 
    f(il); 
} 

त्रुटि है: "क्या अंतर है"

prog.cpp: In function ‘int main()’: 
prog.cpp:10:9: error: could not convert ‘il’ from ‘std::initializer_list<int>’ to ‘x’ 

और अब सवाल का

auto x = {1, 2, 3}; कोड में यह, प्रकार का निर्धारण करने के लिए ठीक है, क्योंकि सांकेतिक शब्दों में बदलनेवाला स्पष्ट रूप से कहा समारोह टेम्पलेट के मामले में वह यह सुनिश्चित करें कि वह अलग प्रकार का उपयोग कर रहा है हो सकता है का उपयोग कर auto

"यह क्या हो रहा है यह है टाइप महत्वपूर्ण नहीं है"। और संदिग्ध मामलों में त्रुटियों को रोकने के लिए अच्छा है (यह सी ++ शैली की तरह प्रतीत नहीं होता है)।

विशेष रूप से खराब यह होगा कि 1 फ़ंक्शन f(x) था और फिर इसे टेम्पलेट में बदल दिया गया था। प्रोग्रामर ने इसे x के रूप में उपयोग करने के लिए लिखा, और दूसरे प्रकार के लिए नया फ़ंक्शन जोड़ने के बाद यह थोड़ा अलग कॉल करने के लिए थोड़ा बदल गया।

+1

मुझे समझ में नहीं आता कि 'ऑटो' का अर्थ यह है कि "यह महत्वपूर्ण नहीं है कि यह किस प्रकार है," लेकिन कह रहा है कि 'टेम्पलेट ' का अर्थ कुछ अलग है। दोनों मामलों में, आप जोखिम को चलाते हैं कि जिस तरह से प्रक्षेपित किया गया प्रोग्राम प्रोग्रामर का इरादा नहीं हो सकता है। – KnowItAllWannabe

+0

मैं दूसरे कोड को समझ नहीं पा रहा हूं। आप लिखते हैं "यह दिखाने के लिए कि यह प्रारंभकर्ता सूची नहीं है" लेकिन उदाहरण में '{1,2,3}' प्रारंभकर्ता सूची है, इसलिए त्रुटि ... – user463035818

+0

मेरा मतलब है कि मैं दिखा रहा हूं कि पहले कोड में यह startizer_list नहीं है। क्योंकि जब यह प्रारंभिक_सूची है तो यह काम नहीं करता है – RiaD

13

वहाँ टेम्पलेट्स किसी भी कटौती

  • भविष्य भाषा एक्सटेंशन के बारे में

    चिंताएं (वहाँ अनेक अर्थ हैं आप जा सकते थे (है कि मैं आरोप में पुरुष के साथ एक चर्चा में याद दो) नहीं करने के लिए के लिए दो महत्वपूर्ण कारण हैं आविष्कार - क्या होगा यदि हम ब्रेस्ड इनिट सूची फ़ंक्शन तर्कों के लिए पूर्ण अग्रेषण शुरू करना चाहते हैं?)

  • ब्रेसिज़ कभी कभी वैध एक समारोह पैरामीटर है कि प्रारंभ कर सकते हैं निर्भर

template<typename T> 
void assign(T &d, const T& s); 
int main() { 
    vector<int> v; 
    assign(v, { 1, 2, 3 }); 
} 

तो Tinitializer_list<int> लेकिन vector<int> के बाईं ओर सही पक्ष पर निष्कर्ष निकाला जा सकता है, यह विरोधाभासी तर्क कटौती के कारण काम करने में विफल रहेगा।

auto से initializer_list<T> के लिए कटौती विवादास्पद है। सी ++ के लिए एक प्रस्ताव है - इसे हटाने के लिए 14 के बाद (और { } या {a, b} के साथ प्रारंभिक प्रतिबंध पर प्रतिबंध लगाने के लिए, और {a}a के प्रकार को कम करने के लिए)।

संबंधित मुद्दे