2013-06-16 4 views
16

सी ++ में एनम के स्ट्रिंग का प्रतिनिधित्व करने का कोई तरीका नहीं है। लोग कस्टम कार्यों कि case XYZ return "XYZ";उपयोगकर्ता परिभाषित एनएम के लिए to_string प्रदान करने के लिए उचित तरीके से परिभाषित उपयोगकर्ता के लिए std :: to_string ओवरराइड कर रहा है?

साथ बॉयलरप्लेट कोड उर्फ ​​
switch का एक बहुत निश्चित रूप से कस्टम समारोह का नाम पता करने के लिए enum के उपयोगकर्ताओं की आवश्यकता है यही कारण है कि शामिल लिख कर इस के आसपास मिलता है।

तो मैंने सोचा कि मैं std::to_string पर एक विशेषज्ञता जोड़ सकता हूं ताकि उपयोगकर्ता को मेरे enums पर to_string का उपयोग करने में सक्षम बनाया जा सके। कुछ इस तरह:

// 
#include <iostream> 
#include <string> 
#include <cassert> 
#define TEST 
class Car 
{ 
public: 
    enum class Color 
    { 
     Red, 
     Blue, 
     White 
    }; 
}; 
#ifdef TEST 
#include <string> 
namespace std 
{ 
    std::string to_string (Car::Color c) 
    { 
     switch (c) 
     { 
     case Car::Color::Red: 
      return "Red"; 
     case Car::Color::Blue: 
      return "Blue"; 
     case Car::Color::White: 
      return "White"; 
     default: 
      { 
       assert(0); 
       return ""; 
      } 
     } 
    } 

} 
#endif 
int main() 
{ 
    std::cout << std::to_string(Car::Color::White) << std::endl; 

} 

क्या इस समाधान के साथ कोई समस्या है?

+4

पर कुछ भी जोड़ने की आवश्यकता नहीं है, मुझे नहीं लगता कि ओवरलोडिंग एसडीडी फ़ंक्शंस की अनुमति है, केवल टेम्पलेट्स की विशेषता है। – chris

+0

दो चीजें: मैं '#define str (x) # x' (और संबंधित' #define गोंद (ए, बी) एक ## बी') का उपयोग देखने के लिए देखता हूं यह देखने के लिए कि क्या कम बॉयलरप्लेट के साथ आपकी ज़रूरतों को पूरा करता है या नहीं । बस इसे सुरक्षा के लिए फ़ंक्शन में लपेटना सुनिश्चित करें, और इसे पूरा करने के ठीक बाद इसे '# undef'' करने के लिए सुनिश्चित करें। दूसरा, और कम महत्वपूर्ण बात यह है कि क्या आप अपने स्विच में 'ब्रेक' भूल गए हैं - संभवतः यदि आप सुपर यूनिट-टेस्टी महसूस नहीं कर रहे हैं तो इसका उपयोग न करें। – FizzixNerd

उत्तर

22

नहीं "अधिभावी" यही है (virtual कार्यों के लिए लागू होता है), और आप नहीं जोड़ा है एक "विशेषज्ञता" (टेम्पलेट्स के लिए लागू होता है), तो आप एक अधिभार, जो एक घोषणा और एक नया की परिभाषा कहते हैं जोड़ दिया है समारोह std नाम स्थान के लिए और कहा कि मना रहा है:

17.6.4.2.1 नाम स्थान एसटीडी [namespace.std]
एक सी ++ प्रोग्राम के व्यवहार अपरिभाषित है अगर यह std या एक के लिए नाम स्थान के लिए घोषणाओं या परिभाषाओं कहते हैं नेमस्पेस std के भीतर नामस्थान जब तक अन्यथा निर्दिष्ट नहीं किया जाता है। एक प्रोग्राम किसी भी मानक लाइब्रेरी टेम्पलेट के लिए किसी भी मानक लाइब्रेरी टेम्पलेट के लिए केवल टेम्पलेट विशेषज्ञता को जोड़ सकता है, यदि घोषणा उपयोगकर्ता द्वारा परिभाषित प्रकार पर निर्भर करती है और विशेषज्ञता मूल टेम्पलेट के लिए मानक लाइब्रेरी आवश्यकताओं को पूरा करती है और स्पष्ट रूप से प्रतिबंधित नहीं है।

एक बेहतर समाधान अपने खुद के नाम स्थान में यह ओवरलोड, और to_string(c) बजाय std::to_string(c) कॉल करने के लिए किया जाएगा। यह सही कार्य मिलेगा और आपको std

+0

प्रतीक्षा करें, मैं उलझन में हूं कि आपका मतलब क्या है "जो नामांकन के लिए एक नए फ़ंक्शन की घोषणा और परिभाषा जोड़ता है" ... to_string std में मौजूद है, है ना? क्या आप फ़ंक्शन के पैरा भाग को मानते हैं, यही कारण है कि आप इसे नया कहते हैं? – NoSenseEtAl

+0

हां, यह एक नया काम है, है ना? यह पहले नहीं था। यह एक नया _name_ नहीं है लेकिन आप एक नया फ़ंक्शन परिभाषित कर रहे हैं। फ़ंक्शन 'std :: to_string (int)' 'std :: to_string (double) 'के लिए एक अलग फ़ंक्शन है और' std :: to_string (कार :: रंग)' –

+3

पर एक अलग फ़ंक्शन है C++ मानक पैरामीटर प्रकारों को मानता है समारोह के भी, यह सिर्फ मुझे नहीं है: ** 1.3.17 [defns.signature] हस्ताक्षर ** नाम, पैरामीटर प्रकार सूची (8.3.5), और नामस्थान संलग्न (यदि कोई हो) –

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