在"char类型"模板化类中使用字符串litterals

gal*_*tte 7 c++ templates widechar

我在C模板类++这需要作为char_type模板参数中的字符类型,如char,wchar_t,char32_t等...的类,然后使用std::basic_string<char_type>在代码中.

然后在课堂的某个地方填写一个表格,例如"&amp;".这并不是因为根据模板字符类型的工作,我们需要使用"&amp;",L"&amp;",U"&amp;"...

有没有办法避免专门用于初始化表的模板函数,例如使用一些标准函数来转换字符串litterals?

由于这些是转义序列,因此它们不包含除ASCII字符之外的任何内容.

Pap*_*ter 4

我会做以下事情:

template <typename char_type, size_t LENGTH>
constexpr std::basic_string<char_type> literal(const char (&value)[LENGTH])
{
    using string = std::basic_string<char_type>;

    string result{};
    result.reserve(LENGTH);

    std::copy(std::begin(value), std::end(value), std::back_inserter(result));

    return result; // rvo
}
Run Code Online (Sandbox Code Playgroud)

您可以这样使用它:

// Table of escaping sequences
std::basic_string<char_type> escaping_sequences[] =
{
    literal<char_type>("&amp"),
    literal<char_type>("&foo"),
    literal<char_type>("&bar"),
    ...
}
Run Code Online (Sandbox Code Playgroud)

我在 Ideone 中测试过:

literal<  char  >("test") // result: std::string
literal<char32_t>("test") // result: std::basic_string<char32_t, std::char_traits<char32_t>, std::allocator<char32_t> >
literal<char16_t>("test") // result: std::basic_string<char16_t, std::char_traits<char16_t>, std::allocator<char16_t> >
Run Code Online (Sandbox Code Playgroud)

未经测试所有字符类型,但希望它有所帮助。

编辑1

糟糕的是,我刚刚注意到加利内特在我之前几乎回答了和我一样的问题。我的代码和 galinette 的代码之间的唯一区别是我将结果字符串分配一次,reserve而不是使用自动分配push_backLENGTH由于使用作为模板参数,因此在编译时计算字符数。

编辑2

通过迭代器减 1 可以避免最终的空字符问题end

template <typename char_type, size_t LENGTH>
constexpr std::basic_string<char_type> literal(const char (&value)[LENGTH])
{
    using string = std::basic_string<char_type>;

    string result{};
    result.reserve(LENGTH - 1);

    std::copy(std::begin(value), std::end(value) - 1, std::back_inserter(result));

    return result; // rvo
}
Run Code Online (Sandbox Code Playgroud)

或者,使用std::copy_n而不是std::copy

template <typename char_type, size_t LENGTH>
constexpr std::basic_string<char_type> literal(const char (&value)[LENGTH])
{
    using string = std::basic_string<char_type>;

    string result{};
    result.reserve(LENGTH - 1);

    std::copy_n(std::begin(value), LENGTH - 1, std::back_inserter(result));

    return result; // rvo
}
Run Code Online (Sandbox Code Playgroud)