2010-03-06 12 views
15

उदाहरण के लिए, अगर मेरे पास है:क्या मैं सी ++ में एनम प्रकारों पर ऑपरेटरों को अधिभारित कर सकता हूं?

typedef enum { year, month, day } field_type; 

inline foo operator *(field_type t,int x) 
{ 
    return foo(f,x); 
} 
inline foo operator -(field_type t) 
{ 
    return t*-1; 
} 
int operator /(distance const &d,field_type v) 
{ 
    return d.in(v); 
} 

अगर मैं इस तरह के ऑपरेटरों यह वास्तव में day*3 लिखने के लिए कानूनी है परिभाषित करने और नहीं है यह 6 में अनुवाद किया जाएगा क्योंकि?

तो यह कानूनी है?

कम से कम जीसीसी और इंटेल संकलक एक चेतावनी के बिना यह स्वीकार करते हैं।

Clearification:

मैं नहीं चाहता कि डिफ़ॉल्ट अंकगणितीय आपरेशनों, मैं अपने ही कार्य है कि गैर पूर्णांक प्रकार वापसी चाहते हैं।

+0

वह 'foo' प्रकार क्या है? – AnT

+0

foo कुछ जटिल डेटा संरचना है उदाहरण के लिए 'struct foo {field_type प्रकार, int मान; } ' – Artyom

उत्तर

7

हाँ, ऑपरेटर ओवरलोडिंग enum और वर्ग प्रकार पर किया जा सकता है। जिस तरह से आप यह कर ठीक है, लेकिन आप + का उपयोग *-1 या कुछ और करने के बजाय, गणन बढ़ावा देने के लिए करना चाहिए (उद्देश्य अंततः अनंत प्रत्यावर्तन से बचने के लिए, क्योंकि -t है):

inline foo operator -(field_type t) { 
    return -+t; 
} 

यह अन्य कार्यों के लिए अच्छी तरह से स्केल करेगा । + एक पूर्णांक प्रकार है कि अपने मूल्य का प्रतिनिधित्व कर सकते करने के लिए गणन को बढ़ावा देंगे, और फिर आप अनंत प्रत्यावर्तन पैदा करने के बिना - आवेदन कर सकते हैं।


सूचना है कि अपने operator* केवल आप enum_type * integer ऐसा करने की अनुमति है, लेकिन चारों ओर नहीं अन्य तरीके से। यह भी दूसरी दिशा पर विचार करने लायक हो सकता है।

यह भी ध्यान दें कि यह हमेशा ऑपरेंड कि builtin ऑपरेटरों को पहले से ही स्वीकार करने के लिए ऑपरेटरों ओवरलोड (यहां तक ​​कि केवल निहित रूपांतरण के आधार पर करते हैं) एक सा खतरनाक है। कल्पना कीजिए distance एक परिवर्तित निर्माता लेने पूर्णांक (distance(int) के रूप में) है, तो दिए गए अपने operator/ निम्नलिखित, अस्पष्ट

// ambiguous: operator/(int, int) (built-in) or 
//   operator/(distance const&, field_type) ? 
31/month; 
इसके लिए

, शायद यह field_type उचित ऑपरेटरों के साथ एक वास्तविक वर्ग बनाने के लिए बेहतर है है ताकि आप शुरू से ही इस तरह के किसी भी निहित रूपांतरण को बाहर कर सकते हैं। एक और अच्छा समाधान सी ++ 0x के enum class द्वारा प्रदान किया जाता है, जो मजबूत गणना प्रदान करता है।

+0

धन्यवाद, यह वास्तव में सहायक था, मैं बस यह सुनिश्चित करना चाहता था कि मैं ऐसा कुछ नहीं करता जो वास्तव में अच्छी तरह परिभाषित नहीं है। – Artyom

-1

हाँ, यह कानूनी है। ईएनएन स्वचालित रूप से मूल्यों को INT में बदल देगा।

enum A { 
    x,y 
}; 

int main() { 
    int z = x * y; 
} 

जवाब दुर्भाग्य से "हाँ" है:

+0

जो बिल्कुल मैं नहीं चाहता हूं। मैं पूछता हूं कि यह अधिभार के लिए कानूनी है? – Artyom

+0

@ आर्टिम: गलत। आपने स्पष्ट रूप से पूछा, "यदि मैं ** ** ऐसे ऑपरेटरों को परिभाषित नहीं करता हूं तो वास्तव में 'दिन * 3' लिखना कानूनी है और इसका अनुवाद' 6' में किया जाएगा? "। यह स्पष्ट रूप से * आपके * प्रश्न का उत्तर है। – AnT

1

आप पूछ रहे हैं, तो इस कोड को कानूनी है। Enum मान से पूर्णांक में एक अंतर्निहित रूपांतरण है।

0

खैर, day * 3 के बारे में अपने प्रश्न का उत्तर है: हाँ, आप यह कर सकते हैं। इसके लिए आपको किसी ऑपरेटर ओवरलोडिंग की आवश्यकता नहीं है। और परिणाम 6 होगा। हालांकि, यह day को int प्रकार में निरंतर करके int प्रकार के गुणा करने और int के परिणाम देने के परिणामस्वरूप काम करेगा, यानी है। जो अगला प्रश्न उठाता है: क्या आप int होने के साथ ठीक हैं?बाद में उस 6 के साथ क्या करने की योजना बना रहे हैं? यदि आपके उद्देश्य के लिए int ठीक है, तो आपको कुछ भी करने की आवश्यकता नहीं है।

हालांकि, यह संभव है कि आप से field_type प्रकार का परिणाम प्राप्त करना चाहते हैं। आप देखते हैं, सी ++ int प्रकार में एनम प्रकारों के लिए स्पष्ट रूप से परिवर्तनीय नहीं है। तो यह संकलन होगा और काम

int product = day * 3; 

लेकिन यह नहीं होगा

field_type product = day * 3; // ERROR 

आप एक स्पष्ट डाली

field_type product = (field_type) (day * 3); 

का उपयोग करके संकलित करने के लिए बाद के लिए मजबूर कर सकते हैं या आप ऑपरेटर के साथ खेल शुरू कर सकते हैं ओवरलोडिंग,

field_type operator *(field_type lhs, int rhs) 
{ 
    return (field_type) ((int) lhs * rhs) 
} 

नोट, कि अधिभारित ऑपरेटर का कार्यान्वयन अभी भी एक कलाकार पर निर्भर करता है, इसलिए यह समर्पित प्रोग्रामरों में बदसूरत जानवरों को घेरकर, आपके प्रोग्राम के "मुख्य" कोड को क्लीनर बनाने का एक तरीका है (इसमें कुछ भी गलत नहीं है)।

एक पैडेंटिक साइड नोट के रूप में, मैं यह जोड़ना चाहता हूं कि पूर्णांक अंकगणितीय परिचालन के परिणामों को एक enum प्रकार में निचोड़ने की कोशिश करने में कुछ औपचारिक खतरे हैं (यदि आप यही चाहते हैं; शायद आप नहीं करते प्रतीत होता है कि आप इसके बारे में कोई विवरण नहीं दे रहे हैं, इसके परिणामस्वरूप आप किसी अन्य प्रकार foo का उपयोग कर रहे हैं)। मानों की श्रेणी एक enum ऑब्जेक्ट का प्रतिनिधित्व कर सकते हैं [मोटे तौर पर] 2^N-1 के अगले उच्चतम (परिमाण) द्वारा संख्याबद्ध गोम के अधिकतम (परिमाण) द्वारा निर्धारित किया गया है। आपके मामले में उच्चतम मूल्य day 2 के बराबर है, जिसका अर्थ है कि आपकी enum को 3 तक मूल्यों का प्रतिनिधित्व करने की गारंटी है। यदि आप 6 को अपने enum प्रकार में कनवर्ट करने का प्रयास करते हैं तो परिणाम अनिर्दिष्ट है (हालांकि यह आमतौर पर अभ्यास में "अपेक्षित" काम करेगा)।

+0

"चूंकि आप किसी अन्य प्रकार के foo का उपयोग कर रहे हैं" वास्तव में मैंने अभी उल्लेख नहीं किया है कि यह सिर्फ एक साधारण वर्ग है जो enum और off दोनों सेट रखती है, इसलिए मैं 'दिनांक + = वर्ष * 3 + माह * 3 + सप्ताह' लिख सकता हूं, जहां कुछ प्रकार पूर्ण ऑफसेट रखेंगे। – Artyom

+0

आपका 'ऑपरेटर * 'कार्यान्वयन अंतहीन रिकर्सन –

+0

@ जोहान्स में समाप्त होगा: आप सही हैं। फिक्स्ड। – AnT

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