2012-12-17 20 views
7

के रूप में संदर्भ का उपयोग करते हुए निम्नलिखित उदाहरण में, Foo इरादा नहीं कर रहा है, लेकिन मुझे यह पता नहीं लगाया जा सकता कि इसे संकलित करने की अनुमति क्यों है।टेम्पलेट प्रकार

#include <string> 
#include <iostream> 

typedef std::string& T; 

T Foo(int & i) 
{ 
    return T(i); 
} 

int main() 
{ 
    int a = 1; 
    std::string & s = Foo(a); 
} 

मैं टेम्पलेट्स के साथ इस खोज की है, लेकिन typedef टेम्पलेट्स के लिए है कि इसके असंबंधित को दर्शाता है। कहने की जरूरत नहीं है, s यहां एक वैध स्ट्रिंग नहीं है। मुझे लगता है कि Foo की वापसी में मूल्य का निर्माण एक संकलन त्रुटि उत्पन्न करेगा।

मुझे यहां क्या याद आ रही है?

+0

यदि आप 'Foo (a);' का आह्वान कर रहे हैं और विशेषज्ञता 'Foo () 'को निकालने की उम्मीद कर रहे हैं तो आपकी विशेषज्ञता को बहुत चौंकाने वाला नहीं कहा जाता है। – WhozCraig

+0

@WozCraig मैं सहमत हूं, मैं निराश था क्योंकि यह समझ में नहीं आया था। – JaredC

+0

यह निश्चित रूप से आग है, अगर आप सीधे 'Foo ()' का आह्वान करते हैं, लेकिन वास्तव में यह वास्तव में नहीं है कि आप आखिरकार क्या खोज रहे हैं, इसमें कोई संदेह नहीं है। – WhozCraig

उत्तर

6

सबसे पहले, यह कुछ भी नहीं लायक है क्योंकि इस कोड एक अच्छी तरह से संकलित है कि समस्या वास्तव में टेम्पलेट्स के लिए कोई संबंध नहीं है:

typedef std::string& T; 
T Foo(int& i) { 
    return T(i); 
} 

कारण मुझे लगता है कि इस संकलित कि return बयान के बराबर है है

return reinterpret_cast<T>(i); 

T मामले में संदर्भ सदस्य होता है। ... और यह, निश्चित रूप से, संकलित करता है: आपने वादा किया था कि आप जानते थे कि आप क्या कर रहे थे और संकलक से आपसे विश्वास करने के लिए कहा।

ठीक है, 5.2.3 पर यह पाया [expr.type.conv] अनुच्छेद 1:

... अभिव्यक्ति सूची एक भी अभिव्यक्ति है, जैसे रूपांतरण अभिव्यक्ति समकक्ष (है definedness में, और यदि अर्थ में परिभाषित किया गया है) संबंधित कास्ट अभिव्यक्ति (5.4) पर। ...

... और 5.4 [expr.cast] पैरा 4:

रूपांतरण के आधार पर [डाले के अन्य रूपों] प्रदर्शन एक reinterpret_cast (5.2.10) [...] स्पष्ट प्रकार रूपांतरण के कास्ट नोटेशन का उपयोग करके किया जा सकता है। [...]

(elisions, उपयोगकर्ता परिभाषित प्रकार से जुड़े मामलों को कवर में निर्मित प्रकार रूपांतरण, const रूपांतरण, आदि)

+0

क्या आप इस मामले में * क्यों * 'reinterpret_cast' पर विस्तार कर सकते हैं जब टी संदर्भ है? – JaredC

+0

वाह, यह सूक्ष्म है, खासकर टेम्पलेट का उपयोग करते समय। मुझे इस मामले में 'टी' के संदर्भ प्रकार को प्रतिबंधित करने के बारे में एक फॉलो अप प्रश्न दिखाई देता है ... – JaredC

+0

इसे रोकने के लिए मेरे उत्तर का अंत देखें –

5

इस टेम्पलेट के साथ कोई संबंध नहीं है, आप एक ही परिणाम प्राप्त यदि T सिर्फ std::string& बजाय एक निष्कर्ष निकाला टेम्पलेट पैरामीटर के लिए एक typedef है:

:

#include <string> 

typedef std::string& T; 

T Foo(int & i) 
{ 
    return T(i); 
} 

int main() 
{ 
    int a = 1; 
    std::string & s = Foo(a); 
} 

डिटमार का जवाब मुझे इस साकार करने के लिए आगे सरल किया जा सकता बना दिया 210

#include <string> 

typedef std::string& T; 

int main() 
{ 
    int a = 1; 
    std::string & s = T(a); 
} 

जहां T(a) डाली (T)a यानी (std::string&)a जो (5.4 [expr.cast] के नियमों के अनुसार) एक const_cast करना होगा कि अगर मान्य है (जो यह नहीं है) के रूप में ही है या एक static_cast यह है कि अगर मान्य है (जो यह नहीं है) या एक static_cast एक const_cast द्वारा पीछा किया है कि यदि मान्य है (जो यह नहीं है) या एक reinterpret_cast कि यदि मान्य है (जो यह है) या एक reinterpret_cast एक const_cast कि यदि मान्य है, जिसके बाद, अन्यथा अभिव्यक्ति खराब है।

तो जैसा कि डिटमार ने कहा, यह एक reinterpret_cast कर के रूप में ही है, यानी

std::string & s = reinterpret_cast<std::string&>(a); 

मुझे लगता है यह काफी आश्चर्य की बात है कि मूल कोड को संकलित करता है, लेकिन के रूप में यह ऊपर है कि रेखा के रूप में ही है, यह संकलन करने की अनुमति दी है । कास्ट के परिणाम का उपयोग करना अनिश्चित व्यवहार हालांकि है।

आश्चर्य से बचने जहां T(a) एक डाली के बराबर है, नई सी ++ 11 वर्दी प्रारंभ वाक्य रचना, T{a} है, जो हमेशा एक प्रारंभ, नहीं एक डाली अभिव्यक्ति है का उपयोग करें।

महान प्रश्न, जांच और जवाब देने से मुझे एक नया गोचा दिखाया गया था, मुझे पहले ज्ञान के नए हिस्से के लिए जेरेडसी और डाइटमार के बारे में पता नहीं था!

+0

क्या टेम्पलेट को दूर करने के लिए प्रश्न संपादित करना उचित है (क्योंकि 2 लोगों ने अब तक टिप्पणी की है)? या मुझे बस छोड़ना चाहिए? – JaredC

+0

मुझे लगता है कि इसे संपादित करना ठीक है ... प्रश्न दिलचस्प है इसलिए टेम्पलेट्स के संबंध में लाल हेरिंग को हटाने के लिए इसे स्पष्ट करना समझ में आता है। –

+0

@ जेरेडसी: मैं जोनाथन से सहमत हूं। बेशक, इसका मतलब यह भी होगा कि बदले गए प्रश्न को ध्यान में रखने के लिए उत्तर संपादित किए जा रहे हैं;) –

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