2013-07-05 14 views
11

initializer_list निम्नलिखित कोडrvalue साथ प्रकार निष्कर्ष

#include <initializer_list> 
#include <utility> 

template<typename T> void f(T&& x) {} 
template<typename T> void g(std::initializer_list<T> x) {} 

int main() 
{ 
    auto x = {0}; // OK 
    auto&& y = {0}; // OK 
    g(x); // OK 
    g(std::move(x)); // OK 
    g({0}); // OK 
    f(x); // OK 
    f(std::move(x)); // OK 
    f({0}); // failure 
    return 0; 
} 

rvalue initializer_listauto लेकिन template साथ नहीं के साथ निष्कर्ष निकाला जा सकता है।

क्यों सी ++ इसे मना करता है?

+1

शायद क्योंकि '{0}' "शाब्दिक प्रारंभकर्ता" का एक प्रकार के रूप में व्यवहार किया जाता है और intuitively आप कर सकते हैं ' एक शाब्दिक से स्थानांतरित नहीं होता है (या उसमें से एक रैल्यू संदर्भ है जिसे आप स्थानांतरित कर सकते हैं)। –

+1

आप रास्ते में '# शामिल करें ' खो रहे हैं। – chris

+0

@ क्रिसिस - आप सही हैं। मैं –

उत्तर

9

मेरा मानना ​​है कि इस 14.8.2.1/1 की वजह से है:

[...] एक प्रारंभकर्ता सूची तर्क पैरामीटर एक गैर-निष्कर्ष निकाला संदर्भ (14.8.2.5) पर विचार किया जाएगा कारण बनता है। [उदाहरण: [...]

template<class T> void g(T); 
g({1,2,3});     // error: no argument deduced for T 

- अंत उदाहरण]

अब आप सोच सकते हैं कि auto सिर्फ टेम्पलेट तर्क कटौती है, लेकिन braced सूचियों के लिए auto में विशेष उपचार प्राप्त करता है 7.1.6.4/6:

auto की घटनाओं को प्रतिस्थापित करने के साथ या तो एक नया आविष्कार डी प्रकार टेम्पलेट पैरामीटर यू या, यदि प्रारंभकर्ता ब्रेस्ड-इनिट-सूची (8.5.4) है, std::initializer_list<U> के साथ। [...] [उदाहरण:

auto x1 = { 1, 2 }; // decltype(x1) is std::initializer_list<int> 

- अंत उदाहरण]

+0

संपादित करूंगा, वहां कुछ अजीब मामला होना चाहिए जिससे समिति केवल –

+1

@ a.lasram को विशेष उपचार दे: मुझे लगता है कि यह 'ऑटो x = {1, 2, 3} की अनुमति देने के लिए चोट नहीं पहुंचाता है; ' , तो आप भी यह हो सकता है। दूसरी ओर, यह * शायद टेम्पलेट तर्क कटौती (मैं रचनाकारों को सोच रहा हूँ) की अनुमति देने के लिए चोट लगी होगी। –

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