2016-10-07 8 views
7

मैं अपने खुद के कलाकारों ऑपरेटरों के साथ एक वर्ग लिखने के लिए कोशिश कर रहा हूँ, लेकिन मैं कई operator= रों'ऑपरेटर =' एसटीडी के लिए अस्पष्ट है :: स्ट्रिंग

मैं नीचे छोटे कोड के साथ समस्या को ठीक करने में कामयाब के साथ मुद्दों कर रहा हूँ

#include <string> 

class X 
{ 
public: 
    operator const char*() const { 
    return "a"; 
    } 
    operator std::string() { 
    return "c"; 
    } 
}; 

void func() 
{ 
    X x; 
    std::string s = ""; 
    s = x; 
} 

मैं समझता हूँ std::basic_string कई असाइनमेंट ऑपरेटर है और इस कारण है कि संकलक भ्रमित हो जाता है कि।

अगर मैं या तो कास्ट ऑपरेटर को हटा देता हूं तो यह काम करता है, लेकिन मैं सोच रहा था कि दोनों ऑपरेटरों को रखने का कोई तरीका था या नहीं।

मेरी कक्षा कास्ट के आधार पर अलग-अलग मूल्यों को वापस कर देगी।

मैं कास्ट को मजबूर करने के लिए static_cast<std::string>(x) का भी उपयोग कर सकता था, लेकिन मैं सोच रहा था कि स्थैतिक कलाकारों के बिना ऐसा करने का कोई तरीका था या नहीं?

+0

's = std :: string (x)' के बारे में कैसे? –

+0

हाँ, एक कलाकार काम करेगा, (जैसा कि मेरी पोस्ट में उल्लिखित है), लेकिन मेरा प्रश्न अधिक है अगर मैं संकलक को संकेत दे सकता हूं कि मुझे क्या उपयोग करना है ताकि मुझे खुद कास्ट का उपयोग करने की आवश्यकता न हो। –

+2

क्या वास्तव में "कंपाइलर को संकेत" नहीं डाला गया है? –

उत्तर

2

KerrekSB suggested रूप में, आप

s = std::string(x); 

वैकल्पिक रूप से उपयोग कर सकते हैं, तो आप एक डाली प्रदर्शन कर सकते हैं:

s = (std::string) x; 
// or 
s = static_cast<std::string>(x); 

एक तीसरा विकल्प (जो मैं जंगल में देखने के लिए नहीं बहुत बार वजह से आशा करता हूं पठनीयता की चिंताओं के लिए) सीधे ऑपरेटर तक पहुंचना है:

s = x.operator std::string(); 

आप क्या रॉबर्टो suggested करते हैं और सिर्फconst char * प्रकार ऑपरेटर की स्पष्ट कास्टिंग मजबूर कर सकते हैं एक अलग एपीआई की दुविधा बनाने के लिए तैयार है (और किसी भी संभावित टूट-फूट को ठीक करने) कर रहे हैं:

class X 
{ 
public: 
    explicit operator const char*() const { 
    return "a"; 
    } 
    operator std::string() { 
    return "c"; 
    } 
}; 

यह संकलक को केवल निहित रूपांतरणों को std::string पर अनुमति देता है, और जब आप उस विशेष ऑपरेटर को आमंत्रित करना चाहते हैं तो आपको const char * पर स्पष्ट रूप से डालने की आवश्यकता होती है।


एक आखिरी बात नोट करने के लिए: यदि आप अन्य वर्गों या तरीकों कि इस विशेष वर्ग का उपभोग होता रचना कर रहे हैं, एक और बात करने की कोशिश करना class X के लिए एक अधिभार उपलब्ध कराने के बजाय परिवर्तित करके जिस तरह से वे इस्तेमाल कर रहे हैं उल्टा करने के लिए है X कुछ और करने के लिए।

अपने एपीआई के काम करने के वैकल्पिक तरीकों पर विचार करना हमेशा अच्छा होता है।

+1

औपचारिक रूप से, 'std :: string (x) 'भी एक * कास्ट * (कार्यात्मक नोटेशन में लिखा गया है) है। – AnT

+0

@ एएनटी 'std :: string (x) 'एक कन्स्ट्रक्टर को आमंत्रित करता है और वास्तविक कलाकार नहीं करता है - संकलक इसे नीचे अनुकूलित कर सकता है, निश्चित रूप से, लेकिन अर्थात् यह हो रहा है कि क्या हो रहा है। – Qix

+0

तो? '(std :: string) x' भी एक कन्स्ट्रक्टर का आह्वान करता है। और हाँ, 'std :: string (x) 'एक कास्ट है, ठीक उसी तरह जैसा कि यह भाषा मानक में परिभाषित किया गया है। ए * कास्ट * भाषा का एक पूरी तरह से वाक्य रचनात्मक तत्व है। एक कास्ट के सेमेन्टिक्स टाइप रूपांतरण के अर्थशास्त्र के लिए उबाल जाता है। उत्तरार्द्ध शामिल प्रकारों पर निर्भर करता है। वास्तव में भाषा स्पष्ट रूप से कहती है कि एक तर्क के साथ एक कार्यात्मक-नोटेशन कास्ट क्लासिक कास्ट-नोटेशन कास्ट समान तर्क के साथ होता है। अर्थात। 'std :: string (x)' cast को '(std :: string) x' cast के बराबर परिभाषित किया गया है। – AnT

2

यदि आप char * cast पर explicit कीवर्ड का उपयोग करते हैं तो आप डिफ़ॉल्ट रूप से std :: string पर कास्टिंग करेंगे।

class X 
{ 
public: 
    explicit operator const char*() const { 
     return "a"; 
    } 
    operator std::string() { 
     return "c"; 
    } 
}; 
यह बाद

अपने डाले:

X x; 
std::string s = ""; 
s = x; 

सफल होगा (और अपने वर्ग के उपयोगकर्ता निर्दिष्ट करना होगा चार * डाली अगर वह अन्य कलाकारों का उपयोग करना चाहता) किसी भी तरह से

, आपकी कक्षा के उपयोगकर्ता के रूप में, यदि दोनों कास्टिंग स्पष्ट हैं तो मुझे पसंद आएगा, इसलिए मुझे पता है कि एक कास्टिंग कब बनाया जा रहा है

+0

यह भी एक अच्छा विकल्प है, हालांकि यह आपके एपीआई के अर्थशास्त्र को थोड़ा बदलता है और कोड ब्रेकेज शुरू कर सकता है (हालांकि यह एक अच्छा ट्रेडऑफ हो सकता है)। उस बारे में सोचा नहीं था। – Qix

+3

आप सही @ क्यूक्स हैं, मैं दोनों स्पष्ट होना पसंद करता हूं, लेकिन मुझे लगता है कि साइमन को यह तय करना चाहिए कि – Roberto

+0

'const char * c = x; 'इस तरह से काम नहीं करेगा। आप एपीआई को दूसरी तरफ तोड़ रहे हैं। – skypjack

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