c++ - 将 char8_t const* 输出到 cout 和 wcout,一个编译一个不编译
问题描述
由于P1423R1为 char8_t、char16_t 和 char32_t 添加了已删除的 ostream 插入器,因此如果我们希望将这些类型流式传输到 ostream,我们暂时需要编写自定义运算符。尝试为 MSVC 2019 16.2.0 Preview 2.0 执行此操作时。
#include <iostream>
#include <string>
using namespace std::literals;
template<typename Tostream>
Tostream&
operator<<( Tostream& os, std::u8string_view string ) {
return os;
}
template<typename Tostream>
Tostream&
operator<<( Tostream& os, char8_t const* string ) {
return os << std::u8string_view( string );
}
/// this must be commented out to compile
//std::ostream&
//operator<<( std::ostream& os, char8_t const* string ) {
// return os << std::u8string_view( string );
//}
int
main() {
std::cout << u8"utf-8";
std::wcout << u8"utf-8";
}
我发现我的模板化尝试成功wcout
但不会编译 for ,cout
除非我取消注释非模板化operator<<
for char8_t const *
。
error C2280: 'std::basic_ostream<char,std::char_traits<char>> &std::operator <<<std::char_traits<char>>(std::basic_ostream<char,std::char_traits<char>> &,const char8_t *)': attempting to reference a deleted function
那么问题来了,在什么情况下是对的?不编译是对的cout
还是编译是错误的wcout
?无论哪种方式,这似乎都是错误。
解决方案
P1423 尚未被 C++20 接受(尽管它确实通过了 Kona 的 LEWG 审查),所以有趣的是微软已经实现了它(部分)。
表现出的行为符合 P1423R1 中指定的行为。在最近的 LWG 审查中,要求也删除宽流的 、 和相关char8_t
重载char16_t
。char32_t
P1423R2 包含该更改,因此示例代码的编译也将在std::wcout
何时/如果实现时失败。该修订版尚未在邮件中发布,但可以在https://rawgit.com/sg16-unicode/sg16/master/papers/p1423r2.html进行预览。
正如@Nicol 提到的,我们还没有就删除的重载的行为达成共识。他们应该隐式转码吗?如果是这样,如何处理转码错误?或者他们应该只是流式传输字节?但是如果codecvt
附加了一个方面会发生什么(它将期望执行编码)。应该有std::u8out
吗?还是我们应该提供更好的转码工具并要求它们被显式调用?SG16 将努力为 C++23 回答这些问题。
推荐阅读
- c# - 自定义价格过滤器的正则表达式
- javascript - 获取sql表中某列的行数
- angular - 具有多个文件夹的生产中的角度错误资产路径
- autodesk-forge - 在 IIS 中托管的网页中访问 api 的问题
- python-3.x - PyPlot 错误“X 和 Y 的大小必须相同”,我在网上找到的所有内容都不起作用
- javascript - 类路径找不到文件
- python - 拆分 JSON python 字符串
- ros - Turtlebot3 启动无法连接到 ttyACM0
- scala - SBT 程序集:您可以在多项目构建中创建一个仅包含一个子项目的程序集 jar 吗?
- javascript - 使用 SCSS 在 React 中添加 div 淡出和 div 的条件渲染