2009-05-15 18 views
23

मेरा हालिया उत्तर, What other useful casts can be used in C++ पर हालिया उत्तरों पर कई टिप्पणियां बताती हैं कि सी ++ रूपांतरणों की मेरी समझ दोषपूर्ण है।सी ++ निहित रूपांतरण

#include <string> 

struct A { 
    A(const std::string & s) {} 
}; 

void func(const A & a) { 
} 

int main() { 
    func("one");     // error 
    func(A("two"));   // ok 
    func(std::string("three")); // ok 
} 

मेरे दावा है कि पहले समारोह कॉल एक त्रुटि है, becauuse वहाँ एक ए के लिए एक स्थिरांक चार * से कोई रूपांतरण वहाँ से एक रूपांतरण है था: बस मुद्दा स्पष्ट करने के लिए, निम्नलिखित कोड पर विचार एक ए के लिए एक स्ट्रिंग, लेकिन इसका उपयोग एक से अधिक रूपांतरण शामिल होगा। मेरी समझ यह है कि इसकी अनुमति नहीं है, और ऐसा लगता है कि यह g ++ 4.4.0 & Comau कंपाइलर्स द्वारा पुष्टि की जाती है। Comeau के साथ, मैं निम्नलिखित त्रुटि मिलती है: आप का कहना है, तो कर सकते हैं, जहां मैं गलत हूँ, यहां पर अथवा मूल जवाब में, अधिमानतः सी ++ मानक के संदर्भ में

"ComeauTest.c", line 11: error: no suitable constructor exists 
     to convert from "const char [4]" to "A" 
     func("one");     // error 

, तो कृपया। उद्धरण प्रदान करने के लिए

At most one user-defined conversion (constructor or conversion function) is implicitly applied to a single value.

अभय के लिए धन्यवाद:

और सी ++ मानक से जवाब हो रहा है।

+0

मुझे खेद है कि मैं आपके उत्तर में टिप्पणी में सभी गलत था। मैंने पढ़ा है "ओवरलोड रिज़ॉल्यूशन का उपयोग उपयोगकर्ता द्वारा परिभाषित रूपांतरण को चुनने के लिए किया जाता है।", और मैंने खुद को 'अच्छी तरह से कहा, तो यह ए (स्ट्रिंग कॉन्स और) को हल करेगा और इसे "एक" पास करेगा, लेकिन मैं पूरी तरह असफल रहा 13.3.3.1.2 के बारे में सोचने के लिए: "उपयोगकर्ता द्वारा परिभाषित रूपांतरण अनुक्रम में प्रारंभिक मानक रूपांतरण अनुक्रम होता है जिसके बाद उपयोगकर्ता परिभाषित रूपांतरण (12.3) होता है जिसके बाद दूसरा मानक रूपांतरण अनुक्रम होता है।" लेकिन "एक" -> स्ट्रिंग एक मानक रूपांतरण अनुक्रम नहीं होगा, लेकिन किसी अन्य उपयोगकर्ता परिभाषित रूपांतरण अनुक्रम की आवश्यकता है! –

+0

बस जब तक मैं अपने पत्थर खो नहीं रहा हूं :-) –

+0

महान सवाल! चर्चा का तात्पर्य है कि 'std :: string' भाषा का हिस्सा नहीं है और इसके द्वारा रूपांतरण "उपयोगकर्ता परिभाषित" हैं। कम से कम यह मेरी समझ है, अगर मैं गलत हूं तो मुझे सही करें। यह अच्छा होगा अगर सवाल इस बारे में अधिक स्पष्ट था। 'Std :: string' की सटीक स्थिति पुरानी सी ++ हाथों के लिए क्रिस्टल-स्पष्ट हो सकती है, लेकिन इस शताब्दी में भाषा में आने वाले लोगों के लिए एहसास करना इतना आसान नहीं है। –

उत्तर

12

मुझे लगता है कि sharptooth का जवाब सटीक है। सी ++ मानक (एससी 22-एन -4411 पीडीएफ) धारा 12.3.4 शीर्षक 'रूपांतरण' यह स्पष्ट करता है कि केवल एक अंतर्निहित उपयोगकर्ता परिभाषित रूपांतरण की अनुमति है।

1 Type conversions of class objects can be specified by constructors and by conversion functions. These conversions are called user-defined conversions and are used for implicit type conversions (Clause 4), for initialization (8.5), and for explicit type conversions (5.4, 5.2.9).

2 User-defined conversions are applied only where they are unambiguous (10.2, 12.3.2). Conversions obey the access control rules (Clause 11). Access control is applied after ambiguity resolution (3.4).

3 [ Note: See 13.3 for a discussion of the use of conversions in function calls as well as examples below. —end note ]

4 At most one user-defined conversion (constructor or conversion function) is implicitly applied to a single value.

+0

मुझे साझा करने के लिए मजबूर होना पड़ता है कि मैं एक विशिष्ट परिदृश्य में निहित रूपांतरणों का उपयोग क्यों करता हूं: अर्थात्, जब मैं एक वर्ग के साथ एक साधारण प्रकार के चर को जोड़ना चाहता हूं जो चर पर संबंधित कार्यों को करता है। निहित रूपांतरण के अलावा, मैं कक्षा में एक फ़ंक्शन प्रदान करता हूं जो मान देता है, उसी तरह std :: string c_str() प्रदान करता है। फिर आपके पास आवश्यक अतिरिक्त कक्षा कार्यक्षमता हो सकती है, और आप संबंधित कार्यक्षमता को एक साथ रखते हुए, कहीं और हल्के वजन वाले जा सकते हैं। – moodboom

8

यह सच है, केवल निहित रूपांतरण की अनुमति है।

एक पंक्ति में दो रूपांतरण एक रूपांतरण ऑपरेटर और पैरामीटरयुक्त कन्स्ट्रक्टर के संयोजन के साथ किया जा सकता है लेकिन इससे C4927 warning - "अवैध रूपांतरण; एक से अधिक उपयोगकर्ता परिभाषित रूपांतरण को लागू किया गया है" - वीसी ++ में कारण।

5

The C++ Programming Language (4। सं।) (खंड 18.4.3) का कहना है कि

only one level of user-defined implicit conversion is legal

अगर कुछ देशी के बीच रहे हैं "उपयोगकर्ता परिभाषित" भाग यह कई अंतर्निहित रूपांतरण की तरह ध्वनि बनाता अनुमति दी जा सकती है कि प्रकार के।

+0

+1। स्ट्रॉस्ट्रप की पुस्तक – mloskot

9

जैसा आम सहमति पहले से ही प्रतीत होती है: हाँ आप सही हैं।

लेकिन चूंकि यह प्रश्न/उत्तर शायद स्टैक ओवरफ्लो पर सी ++ निहित रूपांतरणों के संदर्भ का बिंदु बन जाएगा, मैं इसे टेम्पलेट तर्कों के लिए जोड़ना चाहता हूं नियम नियम अलग हैं।

टेम्पलेट तर्क कटौती के लिए उपयोग किए जाने वाले तर्कों के लिए कोई अंतर्निहित रूपांतरण की अनुमति नहीं है। यह बहुत स्पष्ट प्रतीत हो सकता है लेकिन फिर भी सूक्ष्म अजीबता का कारण बन सकता है।

बिंदु में प्रकरण, std :: स्ट्रिंग अलावा ऑपरेटरों

std::string s; 
s += 67; // (1) 
s = s + 67; // (2) 

(1) संकलित करता है तथा ठीक काम करता है, operator+= एक सदस्य समारोह है, टेम्पलेट चरित्र पैरामीटर पहले से ही रों लिए std::string (instantiating char करने से निष्कर्ष निकाला है)। इसलिए निहित रूपांतरण की अनुमति है (int ->char), जिसके परिणामस्वरूप 67 के समकक्ष समकक्ष होते हैं, उदाहरण के लिएASCII में इस 'सी' बन जाएगा

(2) एक संकलक त्रुटि देता है के रूप में एक नि: शुल्क operator+ समारोह और यहाँ टेम्पलेट चरित्र तर्क कटौती में प्रयोग किया जाता है के रूप में घोषित किया गया है।

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