我在Windows上,我正在std::filesystem::path
构建std::string
。根据构造函数引用(强调我的):
如果源字符类型为
char
,则源的编码将被假定为本机窄编码(因此不会在POSIX系统上进行转换)
如果我理解正确,这意味着字符串内容将被视为在Windows下以ANSI编码。要将其视为以UTF-8编码,我需要使用std::filesystem::u8path()
函数。请参阅演示:http://rextester.com/PXRH65151
我希望path
的构造函数将窄字符串的内容视为UTF-8编码。对于boost::filesystem::path
,我可以使用imbue()
方法执行此操作:
boost::filesystem::path::imbue(std::locale(std::locale(), new std::codecvt_utf8_utf16<wchar_t>()));
但是,我在std::filesystem::path
中没有看到这样的方法。有没有办法为std::filesystem::path
实现这种行为?或者我是否需要在所有地方吐出u8path
?
答案 0 :(得分:1)
出于性能考虑,path
没有全局方式来定义区域设置转换。由于C ++ 11没有UTF-8字符串的特定类型,因此系统假定任何char
字符串都是窄字符串。因此,如果您想使用UTF-8字符串,则必须通过向构造函数提供适当的转换区域设置或使用u8path
来明确拼写它。
答案 1 :(得分:0)
我对此问题的解决方案是将std::filesystem
完全别名为名为std::u8filesystem
的不同命名空间,其中的类和方法将std::string
视为UTF-8编码。类继承具有相同名称的std::filesystem
中的对应项,而不添加任何字段或虚方法来提供完整的API / ABI互操作性。概念代码here的完整证明,仅在Windows上进行了测试,目前为止还远未完成。以下代码段显示了帮助程序的核心工作:
std::wstring U8ToW(const std::string &string);
namespace std
{
namespace u8filesystem
{
#ifdef WIN32
class path : public filesystem::path
{
public:
path(const std::string &string)
: fs::path(U8ToW(path))
{
}
inline std::string string() const
{
return filesystem::path::u8string();
}
}
#else
using namespace filesystem;
#endif
}
}