字符串字面值-字符类型之间的模板转换

string literal - template conversion between char types

本文关键字:转换 之间 类型 字面值 字符 字符串      更新时间:2023-10-16

我想编写一个函数,看起来像:

template <typename CharT>
std::basic_string<CharT> convert(char const *);

的使用方法如下:

convert<char>("Hello World!");     //  "Hello World!"
convert<wchar_t>("Hello World!");  // L"Hello World!"
convert<char16_t>("Hello World!"); // u"Hello World!"
convert<char32_t>("Hello World!"); // U"Hello World!"

我可以使用std::codecvt和co,但我发现它几乎毫无意义,因为使用一些宏以0成本添加L, uU会更容易。

不幸的是,模板和宏在同一级别上不起作用…所以我的问题来了:有没有办法把混合在一起呢?还是有更好的办法?

我的主要目标是避免代码的重复(专门化):我编写的一些函数是CharT模板化的,并使用字符串字面量,这将是唯一的区别。例如:

template <typename CharT>
void foo (std::vector<std::basic_string<CharT>> const & vec, 
          std::basic_string<CharT> str = convert<CharT>("default"));

这样可以避免为每个char类型特化foo()。

非常感谢您的帮助

编辑:这将从C++11工作。由于操作符不能是模板,所以可以将操作符重载更改为convert函数。

#include <string>
std::basic_string<char> operator ""_s(const char * str, std::size_t len) {
    return std::basic_string<char> (str, str + len);
}
std::basic_string<char16_t> operator ""_u(const char * str, std::size_t len) {
    return std::basic_string<char16_t> (str, str + len);
}
std::basic_string<char32_t> operator ""_U(const char * str, std::size_t len) {
    return std::basic_string<char32_t> (str, str + len);
}
std::basic_string<wchar_t> operator ""_L(const char * str, std::size_t len) {
    return std::basic_string<wchar_t> (str, str + len);
}

int main() {
    std::string s1    = "Hello World!"_s;
    std::u16string s2 = "Hello World!"_u;
    std::u32string s3 = "Hello World!"_U;
    std::wstring s4   = "Hello World!"_L;
    return 0;
}

LIVE DEMO working

我终于有了使用宏来生成函数foo的每4次重载的想法。

template <typename CharT>
void foo (std::vector<std::basic_string<CharT>> const & vec, 
          std::basic_string<CharT> str = convert<CharT>("default"));

#define FOO(CharT, prefix) 
void foo (std::vector<std::basic_string<CharT>> const & vec, 
          std::basic_string<CharT> str = prefix ## "default");

我只需要加上

FOO(char, )
FOO(wchar_t, L)
FOO(char16_t, u)
FOO(char32_t, U)

这四行我也可以放到另一个宏GENERATE中所以我可以简单地调用

GENERATE(FOO)

我知道宏…但我已经达到了避免代码重复的主要目标。: -)

谢谢大家的帮助!