निम्नलिखित सरल मानचित्र पर विचार करें:शाब्दिक प्रतिनिधित्व करने के लिए उपयोग किए गए वर्णों के प्रकार द्वारा पैरामीटर किए गए टेम्पलेट के भीतर स्ट्रिंग अक्षर को कैसे व्यक्त किया जाए?
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"));
}
};
यह बुरा है, क्योंकि पूरे तर्क दोहराया गया है: -
समाधान 1MyCoolMap
wchar_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 सकता है:
+1 अच्छा एक। :) –
आपकी समस्या यह है कि तारों की दो सूचियों * एक दूसरे के समान *, वे वास्तव में वही नहीं हैं। – egrunin