C++ 如何在由用于表示字符串的字符类型参数化的模板中表示字符串文本?

C++ 如何在由用于表示字符串的字符类型参数化的模板中表示字符串文本?,c++,C++,考虑以下简单映射: 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")); } }; 当然,

考虑以下简单映射:

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"));
  }
};
当然,这不适用于
C=wchar\u t
。问题是我不知道如何对
char
文本和
wchar\t
文本之间的差异进行模板化。现在我看到两种解决方案,都很丑陋

解决方案1-通过
wchar\t
专门化
mycolmap

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"));
  }
};
模板
类mycolmap:公共无序映射
{
公众:
MyCoolMap()
{
插入(值U类型(L“in1”,L“out1”);
插入(数值类型(L“in2”,L“out2”);
...
插入(价值类型(L“inN”,L“outN”);
}
};
这是不好的,因为整个逻辑是重复的

解决方案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
  }
};
#定义(x)字符串L##x
#定义拖缆(x)\ U拖缆(x)
模板结构特殊_字符串;
#定义DECL_特殊_字符串(STR)\
常数int ss###STR=uuu线uu\
模板结构特殊_字符串{static const char*get_value(){return#STR;}}\
模板结构特殊_字符串{static const wchar_t*get_value(){return TOWSTRING(#STR);};
DECL_特殊_字符串(in1)
DECL_特殊_字符串(out1)
DECL_特殊_字符串(in2)
DECL_特殊_字符串(out2)
...
德克勒特约字符串(客栈)
DECL_特殊_字符串(outN)
模板
类mycolmap:公共无序映射
{
公众:
MyCoolMap()
{
#定义插入映射(in,out)插入(值类型(特殊字符串::获取值(),特殊字符串::获取值())
插入_映射(in1,out1);
插入_映射(in2,out2);
...
插入地图(南部客栈);
#未定义插入映射
}
};
这样我就不需要复制逻辑了,但这太冗长了,而且严重依赖于宏

必须有更好的办法;我就是看不出来

我正在使用VS2010

编辑

我很高兴有人提出了一个简单得多的解决办法——学分归谁。不过,我必须进行一些小的修改才能使其编译:

#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))
#定义(x)字符串L##x
#定义拖缆(x)\ U拖缆(x)
模板常量C*ChooseCW(常量char*C,常量wchar\u t*w);
模板常量char*ChooseCW(常量char*c,常量wchar\u t*w)
{
返回c;
}
模板const wchar_ut*chooscw(const char*c,const wchar_ut*w)
{
返回w;
}
#定义CW(C,STR)选择CW(#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());
}
#包括“stddef.h”
#包括“stdio.h”
模板
类字符串
{
公众:
字符串(常量C*value=deffal):mValue(value){}
常量C*valueOf(){return mValue;}
私人:
常数C*m值;
静态常数C deffal[];
};
常量字符字符串::deffal[]=“char”;
常量wchar_t字符串::deffal[]=L“wchar_t”;
int main(int argc,字符**argv)
{
字符串c(*argv);
字符串w;
返回printf(“%S\n”,w.valueOf());
}

您可能可以对定义进行宏化以避免重复。

使用宏生成两种形式的字符串,并使用模板函数选择要使用的字符串

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")));
模板
常量C*ChooseCW(常量char*C,常量wchar\u t*w);
模板
常量字符*ChooseCW(常量字符*c,常量字符*w)
{
返回c;
}
模板
常量wchar\u t*ChooseCW(常量字符*c,常量wchar\u t*w)
{
返回w;
}
#定义CW(C,STR)选择CW(STR,L##STR)
插入(值_类型(CW(C,“in1”)、CW(C,“out1”));

您的问题是,虽然两个字符串列表彼此相似,但它们实际上并不相同。下面是对Mark想法的改进,保留了结果的数组[count]类型,因此结果可以在sizeof()中使用,就像原始字符串文本:stackoverflow.com/a/63888331/1046167这不正是他所做的吗?很简单,一切都是和蔼可亲的。您的代码片段需要进行一些调整才能编译—将它们作为编辑发布到我的问题中。但除此之外——简直太棒了。@mark,谢谢你的赞扬,谢谢你指出我代码中的错误。我希望现在就可以编译,尽管它与您的想法不同。这里是对您想法的改进,保留了结果的array[count]类型,因此结果可以在sizeof()中使用,就像原始字符串literal:stackoverflow.com/a/63888331/1046167一样
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")));