将char8_t const *输出到cout和wcout,一个不编译 [英] outputting char8_t const* to cout and wcout, one compiles one not

查看:158
本文介绍了将char8_t const *输出到cout和wcout,一个不编译的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

P1423R1 为char8_t,char16_t和char32_t添加已删除的ostream插入器,如果希望将这些类型流式传输到ostream,我们暂时需要编写自定义运算符。尝试对MSVC 2019 16.2.0 Preview 2.0执行此操作时。

Since P1423R1 adds deleted ostream inserters for char8_t, char16_t, and char32_t, we are momentarily left in the situation that we need to write custom operators if we wish to stream these types to ostreams. When attempting to do this for 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 ,但不会为<$​​ c $ c> cout 编译,除非我取消注释非模板化的 operator<< char8_t const *

I find that my templated attempt succeeds for wcout but won't compile for cout unless I uncomment the nontemplated 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 编译是错误的?无论哪种方式,这似乎都是错误。

So the question is, in which case is it right? Is it right not compile for cout or is it wrong to compile for wcout? Either way this appears to be bug.

推荐答案

P1423尚未被C ++ 20接受(尽管它确实通过了)

P1423 hasn't been accepted for C++20 yet (though it did pass LEWG review in Kona), so that is interesting that Microsoft has already implemented (part of) it.

所显示的行为与P1423R1中指定的行为匹配。在最近的LWG审查中,要求 char8_t char16_t char32_t <对于宽泛的流,也将删除/ code>相关的重载。 P1423R2包含了这一更改,因此,如果/如果实现了,则对于 std :: wcout 的示例代码的编译也将失败。该修订版尚未在邮件中发布,但可以在 https://rawgit.com/sg16-unicode/sg16/master/papers/p1423r2.html

The exhibited behavior matches what is specified in P1423R1. During a recent LWG review, it was requested that the char8_t, char16_t, and char32_t related overloads also be deleted for wide streams. P1423R2 includes that change, so compilation of the example code will also fail for std::wcout when/if that is implemented. That revision hasn't been published in a mailing yet, but can be previewed at https://rawgit.com/sg16-unicode/sg16/master/papers/p1423r2.html.

正如@Nicol所说,我们不会尚未就删除的重载的行为达成共识。他们应该隐式转码吗?如果是这样,如何处理转码错误?还是应该只是流字节?但是,如果附加了 codecvt 构面(将会期望执行编码),会发生什么情况。应该有一个 std :: u8out 吗?还是我们应该提供更好的代码转换工具,并要求将其显式调用? SG16将致力于为C ++ 23回答这些问题。

As @Nicol mentioned, we don't yet have consensus for what the behavior of the deleted overloads should be. Should they implicitly transcode? If so, how are errors in transcoding handled? Or should they just stream bytes? But then what happens if a codecvt facet is attached (it will expect execution encoding). Should there be a std::u8out? Or should we provide better transcoding facilities and require they be explicitly invoked? SG16 will be working to answer these questions for C++23.

这篇关于将char8_t const *输出到cout和wcout,一个不编译的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆