在“char类型”模板类中使用字符串

我在C ++中有一个模板类,它将char_type模板参数作为字符类型,例如charwchar_tchar32_t等等。然后,类将在代码中使用std::basic_string<char_type>

然后,我在课堂上的某个地方填写一个转义序列表,如"&amp;" 。 这不依赖于模板字符类型,我们需要使用"&amp;"L"&amp;"U"&amp;" ...

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

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


我会做以下事情:

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
}

你可以这样使用它:

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

我在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> >

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

编辑1

我的坏,我只注意到,在我做之前,galinette几乎和我一样回答。 我的代码和来自galinette的代码之间的唯一区别是,我将reserve的结果字符串分配一次,而不是使用push_back的自动分配来计算编译时的字符数,这是由于使用LENGTH作为模板参数。

编辑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
}

或者,使用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
}

最好的方法是自己定义转换函数,因为将ASCII转换为UTF8 / 16/32对于char类型是一种简单的转换

template<typename char_type>
std::basic_string<char_type> cvtASCIItoUTFX(const char * litteral)
{
    //We could define a faster specialization in case char_type is char

    size_t s = strlen(litteral);

    std::basic_string<char_type> result;
    result.reserve(s);
    for(size_t i=0;i<s;++i)
    {
        result.push_back((char_type)litteral[i]);
    }

    return result;
}

链接地址: http://www.djcxy.com/p/29451.html

上一篇: Use string litterals in a "char type" templated class

下一篇: How to bubble up a rejected promise when using Ember.PromiseProxyMixin