问题
我正在实现一个类,想让用户通过模板参数选择字符串类型 (std::string
, std::wstring
, std::u16string
, ...)。但是我目前无法使字符串字面值与所选的字符串类型匹配:一旦我决定使用字面值前缀 ("hello"
vs. L"hello"
vs. u"hello"
vs. U"hello"
),所有不兼容的字符串类都会出现编译错误。
示例代码
请看以下示例代码(使用--std=c++11
编译):
#include <string>
template<typename StringType>
void hello_string()
{
StringType result("hello");
}
int main()
{
// works
hello_string<std::string>();
hello_string<std::basic_string<char>>();
// the code below does not compile
hello_string<std::wstring>();
hello_string<std::basic_string<unsigned char>>();
hello_string<std::u16string>();
}
hello_string()
函数展示了我想要做的核心:将字符串类型作为模板参数,然后将字符串字面量赋值给此类型的变量。
可能的解决方法
克服我的问题的一种方法是实现hello_string()
函数的几个特化版本。问题在于这会导致每个字符串字面量的多个副本——每个字符串字面量前缀一个。我认为这相当丑陋,并且必须有更好的方法。
另一种方法可能是选择“普通”的字符串字面量作为默认值,并使函数进行不同字符串类型的转换。虽然这可以避免代码重复,但它会引入对实际上是常数的东西进行不必要的转换。
const char kHello[] = "hello"; StringType result(kHello, kHello + sizeof(kHello) - 1);
只适用于纯ASCII。 - Igor Tandetnik