5

मैं असाइनमेंट ऑपरेटर के कई भार के को परिभाषित कर रहा हूँ इस प्रकार है:बूलियन और स्ट्रिंग Overloads

Foo.h

class Foo 
{ 
private: 
    bool my_bool; 
    int my_int; 
    std::string my_string; 
public: 
    Foo& operator= (bool value); 
    Foo& operator= (int value); 
    Foo& operator= (const std::string& value); 
}; 

Foo.cpp

// Assignment Operators. 
Foo& Foo::operator= (bool value) {my_bool = value; return *this;} 
Foo& Foo::operator= (int value) {my_int = value; return *this;} 
Foo& Foo::operator= (const std::string& value) {my_string = value; return *this;} 

और यहां मेरा मुख्य.cpp है (SURPRISE चिह्नित टिप्पणी देखें):

Foo boolFoo; 
Foo intFoo; 
Foo stringFoo; 

// Reassign values via appropriate assignment operator. 
boolFoo = true;    // works...assigned as bool 
intFoo = 42;     // works...assigned as int 
stringFoo = "i_am_a_string"; // SURPRISE...assigned as bool, not string 

std::string s = "i_am_a_string"; 
stringFoo = s;     // works...assigned as string 

// works...but awkward 
stringFoo = static_cast<std::string>("i_am_a_string"); 

प्रश्न: क्या कोई मुझे बता सकता है कि एक बुलियन संदर्भ में एक अज्ञात स्ट्रिंग अक्षर का मूल्यांकन क्यों किया जा रहा है?

+0

@Mooing बतख: क्यों रचनाकारों को हटा दें? मैंने उन्हें जानबूझकर संकेत दिया कि एक परिवर्तक *** कन्स्ट्रक्टर के माध्यम से *** प्रारंभ किया जा सकता है, और उसके बाद *** असाइनमेंट ऑपरेटर के माध्यम से *** पुन: असाइन किया गया। (जैसा कि मैंने अन्य एसओ पोस्ट में देखा है, कभी-कभी आपको *** दोनों *** की आवश्यकता होती है।) – DavidRR

+2

मैंने कोड को छंटनी की है [अच्छे प्रश्नों में एक छोटा आत्म निहित उदाहरण है] (http://sscce.org/) और [आपका कोड काफी छोटा और सरल हो सकता है और अभी भी समस्या को पुन: उत्पन्न कर सकता है] (http://ideone.com/W2nemc)। मैंने पहली बार आपके अधिकांश प्रश्नों को नहीं पढ़ा, क्योंकि इसमें _far_ बहुत अधिक कोड था, और मैंने अनुमान लगाया (सही ढंग से) कि इसमें से अधिकांश आपके प्रश्न से संबंधित नहीं थे। –

+0

@ म्यूइंग डक: हाँ, मैं सिद्धांत में बहुत अधिक सहमत हूं और मेरे उदाहरण में रचनाकार जोड़ते समय इस पर विचार किया। लेकिन मैं यहां आपके फैसले को रोक दूंगा। हालांकि, मेरी आशा यह है कि मेरी टिप्पणी में आने वाले किसी भी व्यक्ति को संबंधित रचनाकारों पर भी विचार करना होगा। – DavidRR

उत्तर

9

सी ++ मानक अध्याय 13.3 में अधिभार संकल्प नियमों को परिभाषित करता है, वहाँ आप पाते हैं:

13.3.3.2 रैंकिंग अंतर्निहित रूपांतरण दृश्यों [over.ics.rank]

जब की तुलना निहित रूपांतरण अनुक्रमों के मूल रूप (जैसा कि 13.3.3.1 में परिभाषित किया गया है)

- एक मानक रूपांतरण अनुक्रम (13.3.3.1.1) उपयोगकर्ता द्वारा परिभाषित एक बेहतर रूपांतरण अनुक्रम है रूपांतरण अनुक्रम या एक इलिप्सिस रूपांतरण अनुक्रम, और

- उपयोगकर्ता द्वारा परिभाषित रूपांतरण अनुक्रम (13.3.3.1.2) एक इलिप्सिस रूपांतरण अनुक्रम (13.3.3.1.3) से बेहतर रूपांतरण अनुक्रम है।

इसका मतलब है कि संकलक bool या int यदि उपलब्ध हो करने के लिए स्ट्रिंग शाब्दिक से एक मानक रूपांतरण अनुक्रम का चुनाव करेगा। अब, कौन से मानक रूपांतरण प्रासंगिक हैं? आपके मामले में, इन दो प्रासंगिक हैं:

4,2 सरणी-टू-सूचक रूपांतरण [conv.array]

एक lvalue या प्रकार के rvalue "NT की सरणी" या "सरणी टी के अज्ञात बंधन के "प्रकार के सूचक" के रूप में परिवर्तित किया जा सकता है "सूचक से टी"। परिणाम सरणी के पहले तत्व के लिए एक सूचक है।

यह रूपांतरण स्ट्रिंग अक्षरल को बदलता है, जो const char[N] प्रकार const char* में है। दूसरा एक है:

4,12 बूलियन रूपांतरण [conv.bool]

एक गणित, unscoped गणन, सूचक, या सूचक सदस्य प्रकार के prvalue के prvalue में बदला जा सकता bool टाइप करें। शून्य मान, शून्य सूचक मान, या शून्य सदस्य सूचक मान को false में परिवर्तित कर दिया गया है; कोई अन्य मान true में परिवर्तित कर दिया गया है। प्रकार std::nullptr_t का एक प्रकार bool प्रकार के प्रसार में परिवर्तित किया जा सकता है; परिणामी मान false है।

यही कारण है कि सूचक bool में परिवर्तित हो गया है। चूंकि एक मानक रूपांतरण अनुक्रम मौजूद है, उपयोगकर्ता द्वारा परिभाषित रूपांतरण std::string का उपयोग नहीं किया जाता है।

अपनी समस्या का समाधान करने के लिए, मेरा सुझाव है कि आप एक और ओवरलोडेड संस्करण जोड़ें जो const char* लेता है और इसे const std::string& ओवरलोड पर कॉल अग्रेषित करता है।

+0

धन्यवाद, डैनियल! मेरे लिए दूसरा सबक यह है कि एक स्ट्रिंग शाब्दिक मानचित्र 'char * '(' char [N] 'के माध्यम से), * नहीं *' std :: string'। – DavidRR

+1

@ डेविड आरआर: उनको 'कॉन्स चार *' और 'कॉन्स्ट चार [एन]' होना चाहिए, लेकिन हां। मानक उद्धृत करने और इसे समझाए जाने के लिए –

+0

+1। –

3

डैनियल सही है।

संक्षिप्त उत्तर यह है कि std::string एक अंतर्निहित प्रकार नहीं है और, इस तरह, किसी भी जादुई अधिमान्य उपचार नहीं मिलता है। और, दुर्भाग्यवश, "hi world" जैसे स्ट्रिंग अक्षर का प्रकार std::string है, लेकिन एक सूचक प्रकार जो आसानी से अंतर्निहित प्रकार bool "उपयोगकर्ता द्वारा परिभाषित" और डैगर से अधिक आसानी से परिवर्तित हो जाता है; टाइप std::string

असल में, जवाब है: सी ++ में आपका स्वागत है।

और डैगर; हाँ, मुझे पता है, यह मानक लाइब्रेरी से है और, नहीं, इससे कोई फर्क नहीं पड़ता।

+0

मुझे लगता है कि किसी ने नीचे गिरा दिया क्योंकि आखिरी वाक्य थोड़ा सा घबराहट के रूप में आता है। –

+2

@Mooing: यदि यह snarky है, तो यह सी ++ पर snarky है। अगर कोई व्यक्तिगत रूप से _that_ ले रहा है, तो, वे मेरी मदद से परे हैं। –

+0

प्रश्न पोस्टर के रूप में, मैं "सी ++ में आपका स्वागत है" से नाराज नहीं हूं। मुझे जावा और सी # से काफी अलग होने के लिए सी ++ मिल रहा है। सी ++ के साथ, यह निश्चित रूप से लगता है कि परेशानी में आने के अधिक अवसर हैं ... – DavidRR