为什么"std::<char16_t>basic_ifstream"在 c++11 中不起作用?

Why does `std::basic_ifstream<char16_t>` not work in c++11?

本文关键字:c++11 不起作用 ifstream gt char16 lt 为什么 std basic      更新时间:2023-10-16

以下代码按预期工作。源代码,文件" file.txt"answers" out.txt"都用UTF8编码。但是,当我在main()的第一行中将wchar_t更改为char16_t时,它不起作用。我尝试使用-std=c++11尝试使用GCC5.4和Clang8.0。我的目标是用char16_t替换wchar_t,因为wchar_t在RAM中取了两次空间。我认为这两种类型在C 11和更高版本的标准中得到了很好的支持。我在这里想念什么?

#include<iostream>
#include<fstream>
#include<locale>
#include<codecvt>
#include<string>
int main(){
  typedef wchar_t my_char;
  std::locale::global(std::locale("en_US.UTF-8"));
  std::ofstream out("file.txt");
  out << "123正则表达式abc" << std::endl;
  out.close();
  std::basic_ifstream<my_char> win("file.txt");
  std::basic_string<my_char> wstr;
  win >> wstr;
  win.close();
  std::ifstream in("file.txt");
  std::string str;
  in >> str;
  in.close();
  std::wstring_convert<std::codecvt_utf8<my_char>, my_char> my_char_conv;
  std::basic_string<my_char> conv = my_char_conv.from_bytes(str);
  std::cout << (wstr == conv ? "true" : "false") << std::endl;
  std::basic_ofstream<my_char> wout("out.txt");
  wout << wstr << std::endl << conv << std::endl;
  wout.close();
  return 0;
}

编辑

修改后的代码不使用Clang8.0编译。它用gcc5.4编译,但在运行时崩溃,如@brian。

各种流类都需要一组定义要运行。标准库仅需要charwchar_t的相关定义和对象,但对于char16_tchar32_t不需要。在我的头顶上,需要以下内容使用std::basic_ifstream<cT>std::basic_ofstream<cT>

  1. std::char_traits<cT>指定字符类型的行为。i Think 此模板专门用于char16_tchar32_t
  2. 所使用的std::locale需要包含一个std::num_put<cT> Facet的实例,以格式化数字类型。可以仅实例化此方面,并且可以创建一个新的std::locale,但标准并不要求它存在于std::locale对象中。
  3. 使用的std::locale需要包含一个facet std::num_get<cT>的实例才能读取数字类型。同样,可以实例化此方面,但默认情况下不需要出现。
  4. 需要专业化Facet std::numpunct<cT>并将其放入使用的std::locale中,以处理小数点,千分离器和文本布尔值。即使没有真正使用,它也会从数字格式和解析功能中引用。char16_tchar32_t没有准备好的专业化。
  5. Facet std::ctype<cT>需要专业化并放入使用的方面,以支持角色类型的扩大,缩小和分类。char16_tchar32_t没有现成的专业化。
    1. 需要专门化Facet std::codecvt<cT, char, std::mbstate_t>并将其放入使用的std::locale中,以在外部字节序列和内部"字符"序列之间转换。char16_tchar32_t没有准备专业化。

大多数方面都很容易做到:他们只需要转发简单的转换或进行桌子查找即可。但是, std::codecvt方面往往很棘手,尤其是因为从标准C 库的角度来看,std::mbstate_t是不透明的类型。

所有这些都可以完成。自从我上次为角色类型做概念实现以来已经有一段时间了。我花了大约一天的工作。当然,我知道以前实施了Locales和Iostreams库时,我知道我需要做什么。要添加合理数量的测试,而不仅仅是进行简单的演示可能会花我一周左右(假设我实际上可以专注于这项工作)。