मैंने आज इस चक्र का पुन: आविष्कार किया, और सोचा कि मैं इसे साझा करूंगा।
इस कार्यान्वयन करता नहीं कोड कि स्थिरांक है, जो enumerations या #define
रों या कुछ और कि एक पूर्णांक के लिए devolves हो सकता है परिभाषित करता है के लिए किसी भी परिवर्तन की आवश्यकता - मेरे मामले में मैं प्रतीकों अन्य प्रतीक के रूप में परिभाषित किया था। यह स्पैस मूल्यों के साथ भी अच्छी तरह से काम करता है। यह एक ही मूल्य के लिए कई नामों को भी अनुमति देता है, हमेशा पहले को लौटता है। केवल नकारात्मक पक्ष यह है कि आपको स्थिरांक की एक तालिका बनाने की आवश्यकता होती है, जो कि पुराने हो सकता है क्योंकि उदाहरण के लिए नए जोड़े गए हैं।
struct IdAndName
{
int id;
const char * name;
bool operator<(const IdAndName &rhs) const { return id < rhs.id; }
};
#define ID_AND_NAME(x) { x, #x }
const char * IdToName(int id, IdAndName *table_begin, IdAndName *table_end)
{
if ((table_end - table_begin) > 1 && table_begin[0].id > table_begin[1].id)
std::stable_sort(table_begin, table_end);
IdAndName searchee = { id, NULL };
IdAndName *p = std::lower_bound(table_begin, table_end, searchee);
return (p == table_end || p->id != id) ? NULL : p->name;
}
template<int N>
const char * IdToName(int id, IdAndName (&table)[N])
{
return IdToName(id, &table[0], &table[N]);
}
कैसे आप इसका उपयोग का एक उदाहरण:
static IdAndName WindowsErrorTable[] =
{
ID_AND_NAME(INT_MAX), // flag value to indicate unsorted table
ID_AND_NAME(NO_ERROR),
ID_AND_NAME(ERROR_INVALID_FUNCTION),
ID_AND_NAME(ERROR_FILE_NOT_FOUND),
ID_AND_NAME(ERROR_PATH_NOT_FOUND),
ID_AND_NAME(ERROR_TOO_MANY_OPEN_FILES),
ID_AND_NAME(ERROR_ACCESS_DENIED),
ID_AND_NAME(ERROR_INVALID_HANDLE),
ID_AND_NAME(ERROR_ARENA_TRASHED),
ID_AND_NAME(ERROR_NOT_ENOUGH_MEMORY),
ID_AND_NAME(ERROR_INVALID_BLOCK),
ID_AND_NAME(ERROR_BAD_ENVIRONMENT),
ID_AND_NAME(ERROR_BAD_FORMAT),
ID_AND_NAME(ERROR_INVALID_ACCESS),
ID_AND_NAME(ERROR_INVALID_DATA),
ID_AND_NAME(ERROR_INVALID_DRIVE),
ID_AND_NAME(ERROR_CURRENT_DIRECTORY),
ID_AND_NAME(ERROR_NOT_SAME_DEVICE),
ID_AND_NAME(ERROR_NO_MORE_FILES)
};
const char * error_name = IdToName(GetLastError(), WindowsErrorTable);
IdToName
समारोह std::lower_bound
पर निर्भर करता है जल्दी लुकअप, जो मेज अनुसार क्रमबद्ध करने की आवश्यकता है क्या करना है। यदि तालिका में पहली दो प्रविष्टियां क्रम से बाहर हैं, तो फ़ंक्शन इसे स्वचालित रूप से सॉर्ट करेगा।
संपादित करें: एक टिप्पणी ने मुझे एक ही सिद्धांत का उपयोग करने का एक और तरीका बताया है। एक मैक्रो एक बड़े switch
कथन की पीढ़ी को सरल बनाता है।
#define ID_AND_NAME(x) case x: return #x
const char * WindowsErrorToName(int id)
{
switch(id)
{
ID_AND_NAME(ERROR_INVALID_FUNCTION);
ID_AND_NAME(ERROR_FILE_NOT_FOUND);
ID_AND_NAME(ERROR_PATH_NOT_FOUND);
ID_AND_NAME(ERROR_TOO_MANY_OPEN_FILES);
ID_AND_NAME(ERROR_ACCESS_DENIED);
ID_AND_NAME(ERROR_INVALID_HANDLE);
ID_AND_NAME(ERROR_ARENA_TRASHED);
ID_AND_NAME(ERROR_NOT_ENOUGH_MEMORY);
ID_AND_NAME(ERROR_INVALID_BLOCK);
ID_AND_NAME(ERROR_BAD_ENVIRONMENT);
ID_AND_NAME(ERROR_BAD_FORMAT);
ID_AND_NAME(ERROR_INVALID_ACCESS);
ID_AND_NAME(ERROR_INVALID_DATA);
ID_AND_NAME(ERROR_INVALID_DRIVE);
ID_AND_NAME(ERROR_CURRENT_DIRECTORY);
ID_AND_NAME(ERROR_NOT_SAME_DEVICE);
ID_AND_NAME(ERROR_NO_MORE_FILES);
default: return NULL;
}
}
संभावित डुप्लिकेट [सी में स्ट्रिंग के रूप में enum प्रकारों के चर का उपयोग करने का आसान तरीका?] (Http://stackoverflow.com/questions/147267/easy-way-to-use-variables-of-enum-types- as-string-in-c) – karlphillip
मैक्रो आधारित फैक्ट्री के बारे में उत्तर http://stackoverflow.com/questions/147267/easy-way-to-use-variables-of-enum-types-as-string-in- सी # 202511 - प्रश्न अद्यतन होने के बाद, यह अब प्रासंगिक नहीं है। – Suma