Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
String 为不同的字符串类拟合字符串文本 问题_String_Templates_C++11_Literals_Prefix - Fatal编程技术网

String 为不同的字符串类拟合字符串文本 问题

String 为不同的字符串类拟合字符串文本 问题,string,templates,c++11,literals,prefix,String,Templates,C++11,Literals,Prefix,我正在实现一个类,其中我想让用户通过模板参数选择字符串类型(std::string,std::wstring,std::u16string,…)。我目前无法使字符串文字符合所选的字符串类型:一旦我决定使用文字前缀(“hello”vs.L“hello”vs.u“hello”vs.u“hello”),我就会得到所有不兼容字符串类的编译错误 玩具示例 作为一个例子,考虑下面的代码(编译为 -STD= C++ 11 ): #包括 模板 void hello_string() { StringType结果

我正在实现一个类,其中我想让用户通过模板参数选择字符串类型(
std::string
std::wstring
std::u16string
,…)。我目前无法使字符串文字符合所选的字符串类型:一旦我决定使用文字前缀(
“hello”
vs.
L“hello”
vs.
u“hello”
vs.
u“hello”
),我就会得到所有不兼容字符串类的编译错误

玩具示例

作为一个例子,考虑下面的代码(编译为<代码> -STD= C++ 11 ):

#包括
模板
void hello_string()
{
StringType结果(“你好”);
}
int main()
{
//工作
hello_string();
hello_string();
//下面的代码无法编译
hello_string();
hello_string();
hello_string();
}
函数
hello\u string()
显示了我想要做的事情的本质:将字符串类型作为模板参数,并将字符串文本分配给此类型的变量

可能的解决办法 解决我的问题的一种方法是实现
hello\u string()
函数的几个专门化。问题是,这将导致每个字符串文字的多个副本-每个字符串文字前缀一个副本。我觉得这很难看,一定有更好的办法


另一种方法是选择“普通”字符串文本作为默认值,并让函数对不同的字符串类型进行转换。虽然这样可以避免代码重复,但会引入不必要的常量转换。

您可以自己创建一个宏。首先定义一个包装字符的结构,选择:

namespace details {

    template<typename T>
    struct templ_text;

    template<>
    struct templ_text <char>
    {
        typedef char char_type;
        static const char_type * choose(const char * narrow, const wchar_t * wide, const char16_t* u16, const char32_t* u32) { return narrow; }
        static char_type choose(char narrow, wchar_t wide, char16_t u16, char32_t u32) { return narrow; }
    };

    template<>
    struct templ_text < wchar_t >
    {
        typedef wchar_t char_type;
        static const char_type* choose(const char * narrow, const wchar_t * wide, const char16_t* u16, const char32_t* u32) { return wide; }
        static char_type choose(char narrow, wchar_t wide, char16_t u16, char32_t u32) { return wide; }
    };

    template<>
    struct templ_text < char16_t >
    {
        typedef char16_t char_type;
        static const char_type* choose(const char * narrow, const wchar_t * wide, const char16_t* u16, const char32_t* u32) { return u16; }
        static char_type choose(char narrow, wchar_t wide, char16_t u16, char32_t u32) { return u16; }
    };

    template<>
    struct templ_text < char32_t >
    {
        typedef char32_t char_type;
        static const char_type* choose(const char * narrow, const wchar_t * wide, const char16_t* u16, const char32_t* u32) { return u32; }
        static char_type choose(char narrow, wchar_t wide, char16_t u16, char32_t u32) { return u32; }
    };
}
名称空间详细信息{
模板
结构模板文本;
模板
结构模板文本
{
typedef char_类型;
静态常量字符类型*选择(常量字符*窄,常量wchar\u t*宽,常量字符16\u t*u16,常量字符32\u t*u32){返回窄;}
静态char_类型选择(char窄,wchar_t宽,char16_t u16,char32_t u32){return窄;}
};
模板
结构模板文本
{
typedef wchar_t char_type;
静态const char_type*选择(const char*窄,const wchar_t*宽,const char16_t*u16,const char32_t*u32){return wide;}
静态char_类型选择(char窄,wchar_t宽,char16_t u16,char32_t u32){return wide;}
};
模板
结构模板文本
{
typedef char16_t char_type;
静态常量字符类型*选择(常量字符*窄,常量字符*宽,常量字符16\u t*u16,常量字符32\u t*u32){return u16;}
静态字符类型选择(字符窄,字符宽,字符16,字符32){return u16;}
};
模板
结构模板文本
{
typedef char32_t char_type;
静态常量字符类型*选择(常量字符*窄,常量字符*宽,常量字符16\u t*u16,常量字符32\u t*u32){return u32;}
静态字符类型选择(字符窄,字符宽,字符16,字符32){return u32;}
};
}
将其包装成一个漂亮的宏:

#define TEMPL_TEXT(Ch, txt) details::templ_text<Ch>::choose(txt, L##txt, u##txt, U##txt)
#定义模板文本(Ch,txt)详细信息::模板文本::选择(txt,L##txt,u##txt,u##txt)
那么您的功能将是:

template<typename StringType>
void hello_string()
{
    StringType result(TEMPL_TEXT(typename StringType::value_type, "Hello"));
}
模板
void hello_string()
{
StringType结果(TEMPL_TEXT(typename StringType::value_type,“Hello”);
}

我认为字符串的未使用副本将被优化掉。

const char kHello[]=“hello”;StringType结果(kHello,kHello+sizeof(kHello)-1)仅适用于普通ASCII。谢谢,我忘记了此构造函数类型对于所有基本字符串都是通用的。谢谢您的回答!我知道有一种方法可以通过宏添加文字前缀,但我找不到一种方法将其与模板结合起来。
template<typename StringType>
void hello_string()
{
    StringType result(TEMPL_TEXT(typename StringType::value_type, "Hello"));
}