2012-01-27 6 views
10

निम्नलिखित सरल मानचित्र पर विचार करें:शाब्दिक प्रतिनिधित्व करने के लिए उपयोग किए गए वर्णों के प्रकार द्वारा पैरामीटर किए गए टेम्पलेट के भीतर स्ट्रिंग अक्षर को कैसे व्यक्त किया जाए?

class MyCoolMap : public unordered_map<const char *, const char *> 
{ 
public: 
    ProtoTypeMap() 
    { 
    insert(value_type("in1", "out1")); 
    insert(value_type("in2", "out2")); 
    ... 
    insert(value_type("inN", "outN")); 
    } 
}; 

अब, मान लीजिए मैं char और wchar_t स्ट्रिंग्स के लिए इस नक्शे दोनों उपलब्ध बनाने के लिए की जरूरत है। तो, मैं इसे इस प्रकार पुनर्लेखन:

template<class C> 
class MyCoolMap : public unordered_map<const C *, const C *> 
{ 
public: 
    MyCoolMap() 
    { 
    insert(value_type("in1", "out1")); 
    insert(value_type("in2", "out2")); 
    ... 
    insert(value_type("inN", "outN")); 
    } 
}; 

और, बेशक, इस C=wchar_t के लिए काम नहीं करता। समस्या यह है कि मुझे नहीं पता कि char अक्षरों और wchar_t अक्षरों के बीच अंतर को कैसे टेम्पलेट करना है। अभी मैं दो समाधान देखता हूं, दोनों बदसूरत। ,

template<> 
class MyCoolMap<wchar_t> : public unordered_map<const wchar_t *, const wchar_t *> 
{ 
public: 
    MyCoolMap() 
    { 
    insert(value_type(L"in1", L"out1")); 
    insert(value_type(L"in2", L"out2")); 
    ... 
    insert(value_type(L"inN", L"outN")); 
    } 
}; 

यह बुरा है, क्योंकि पूरे तर्क दोहराया गया है: -

समाधान 1MyCoolMapwchar_t द्वारा विशेषज्ञ हैं।

समाधान 2 - समाधान की तरह एक लक्षण:

#define _TOWSTRING(x) L##x 
#define TOWSTRING(x) _TOWSTRING(x) 

template <class C, int> struct special_string; 
#define DECL_SPECIAL_STRING(STR) \ 
const int ss_##STR = __LINE__; \ 
template<> struct special_string<char, ss_##STR> { static const char *get_value() { return #STR; } }; \ 
template<> struct special_string<wchar_t, ss_##STR> { static const wchar_t *get_value() { return TOWSTRING(#STR); } }; 

DECL_SPECIAL_STRING(in1) 
DECL_SPECIAL_STRING(out1) 
DECL_SPECIAL_STRING(in2) 
DECL_SPECIAL_STRING(out2) 
... 
DECL_SPECIAL_STRING(inN) 
DECL_SPECIAL_STRING(outN) 

template<class C> 
class MyCoolMap : public unordered_map<const C *, const C *> 
{ 
public: 
    MyCoolMap() 
    { 
#define INSERT_MAPPING(in, out) insert(value_type(special_string<C, ss_##in>::get_value(), special_string<C, ss_##out>::get_value())) 
    INSERT_MAPPING(in1, out1); 
    INSERT_MAPPING(in2, out2); 
    ... 
    INSERT_MAPPING(inN, outN); 
#undef INSERT_MAPPING 
    } 
}; 

इस तरह से मैं तर्क को दोहराने की जरूरत नहीं है, लेकिन यह इतना वर्बोज़ है और मैक्रो पर काफी निर्भर करता।

एक बेहतर तरीका होना चाहिए; मैं बस इसे नहीं देखता हूँ।

मैं वीएस -2010 का उपयोग कर रहा हूं।

संपादित

मुझे खुशी है कि एक बहुत सरल समाधान का प्रस्ताव है हूँ - क्रेडिट https://stackoverflow.com/users/5987/mark-ransom में जाते हैं। मुझे इसे संकलित करने के लिए मामूली सुधार करना पड़ा, हालांकि:

#define _TOWSTRING(x) L##x 
#define TOWSTRING(x) _TOWSTRING(x) 

template<typename C> const C * ChooseCW(const char * c, const wchar_t * w); 
template<> const char * ChooseCW<char>(const char * c, const wchar_t * w) 
{ 
    return c; 
} 
template<> const wchar_t *ChooseCW<wchar_t>(const char * c, const wchar_t * w) 
{ 
    return w; 
} 

#define CW(C, STR) ChooseCW<C>(#STR, TOWSTRING(#STR)) 

धन्यवाद।

#include "stddef.h" 
#include "stdio.h" 
template<class C> 
class String 
{ 
    public: 
    String(const C* value = defVal) : mValue(value) {} 
    const C* valueOf() { return mValue; } 
    private: 
    const C* mValue; 
    static const C defVal[]; 
}; 
const char String<char>::defVal[] = "char"; 
const wchar_t String<wchar_t>::defVal[] = L"wchar_t"; 
int main(int argc, char **argv) 
{ 
    String<char> c(*argv); 
    String<wchar_t> w; 
    return printf("%S\n", w.valueOf()); 
} 

आप शायद उन्हें डुप्लिकेट करने से बचने के लिए परिभाषाएँ macroise सकता है:

+0

+1 अच्छा एक। :) –

+2

आपकी समस्या यह है कि तारों की दो सूचियों * एक दूसरे के समान *, वे वास्तव में वही नहीं हैं। – egrunin

उत्तर

9

स्ट्रिंग के दोनों रूपों को उत्पन्न करने के लिए एक मैक्रो का उपयोग करें, और टेम्पलेट फ़ंक्शन का उपयोग करने के लिए चुनें।

template<typename C> 
const C * ChooseCW(const char * c, const wchar_t * w); 

template<> 
const char * ChooseCW<char>(const char * c, const wchar_t * w) 
{ 
    return c; 
} 

template<> 
const wchar_t * ChooseCW<wchar_t>(const char * c, const wchar_t * w) 
{ 
    return w; 
} 

#define CW(C, STR) ChooseCW<C>(STR, L##STR) 

insert(value_type(CW(C, "in1"), CW(C, "out1"))); 
+0

सरल, सभी जो कि जिज्ञासु है। आपके कोड स्निपेट को संकलित करने के लिए कुछ बदलावों की आवश्यकता होती है - उन्हें मेरे प्रश्न के संपादन के रूप में पोस्ट करना। लेकिन अन्यथा - बस आश्चर्यजनक। – mark

+0

@mark, कुडोस के लिए धन्यवाद और मेरे कोड में त्रुटियों को इंगित करने के लिए धन्यवाद। मुझे उम्मीद है कि यह अब संकलित है, भले ही यह आपके जैसा नहीं है। –

-1

सभी स्ट्रिंग स्थिरांक स्थिर सदस्यों, कुछ इस तरह करते हैं।

+0

क्या वह ठीक नहीं है? –

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