Kri*_*ege 12 c++ stl ostream language-lawyer
在我看来,C++标准中存在不一致性,特别是在C++ 17草案(N4659)的§30.7.5.2.4中,关于何时在输出流(operator<<())的格式化输出操作中扩展字符.完全相同的不一致似乎反映在en.cppreference.com中.
首先,假设以下声明:
std::ostream out;
std::wostream wout;
char ch;
wchar_t wch;
const char* str;
const wchar_t* wstr;
Run Code Online (Sandbox Code Playgroud)
然后说明
out << ch 不执行字符扩展,out << str 进行角色拓宽,wout << ch 进行角色拓宽,wout << str 进行角色拓宽,wout << wch 不执行字符扩展,wout << wstr 执行字符扩展.第一个也是最明显的不一致是(6)不可能是真的,因为没有widen()函数采用wchar_t参数,只有一个char参数.
第二个(看似)不一致是在(1)和(2)之间.对我而言,out << "x"应该扩大'x',但out << 'x'不应该扩大.
我是否误解了标准文本,或者那里有什么问题?如果后者是真的,你知道预期的行为是什么吗?
编辑:显然,这种不一致(如果我是对的),至少从C++ 03(§27.6.2.5.4)开始就存在于标准中.文本在中间标准上有所改变,但正如我在上面解释的那样,不一致仍然存在.
看起来标准不完全正确.大多数问题源于相应操作的批量规范.不是单独处理每个过载,而是一起描述相似的过载,导致误导性的规范.
我怀疑,任何实施者都无法理解预期的内容.实质上,当a char插入到非char流中时,需要widen()编辑该字符以获取流的字符类型的字符.此扩展旨在将源字符集中的一个字符映射到流的宽字符集中的一个字符.
请注意,IOStreams规范假定流中的字符的原始概念是单个实体.由于创建了规范(对于C++ 1998版本),文本实际上并没有真正更新,但是广泛使用Unicode,流中的"字符"实际上是编码的字节.虽然这些流在这个修改过的环境中大部分都可以运行,但是有一些灵活性可以帮助处理Unicode字符.缺少将一个字符"扩展"为UTF8字节序列的东西可能就是其中之一.
如果您认为流的部分中的不一致/不正确需要进行寻址,请提交缺陷报告.有关提交缺陷报告的说明,请访问http://isocpp.org.当您提出问题时,请考虑提供建议的措辞来纠正问题.由于目前并不缺乏明确的实际意图,可能大多数实现都是正确的,无论如何我都希望这个问题得到相当低的优先级,如果没有提出措辞,它就不太可能受到太多关注.当然,解决这个问题不会改变预期的行为,例如,将"扩展" char为UTF8序列:这实际上是对流库的重新设计,这可能是有序的,但不会作为缺陷解决.