推理类型如何工作"auto"和按引用调用?



&c如何在这个循环和分配中工作,c = toupper(c)

string str = "hello";
for (auto & c: str)
c = toupper(c);

你能解释一下吗?

首先,请注意,如果std::toupper提供除EOF以外的负值,则它具有未定义的行为。对于大多数编译器,默认情况下char是有符号类型。在典型的 8 位字节计算机上,这意味着如果c的值不在 ASCII 范围内,即 0 到 127,则它是负数,并且会得到 UB。

该问题的简单解决方案是将参数转换为unsigned char

auto to_upper( const char c )
-> char
{
using Byte = unsigned char;
return static_cast<char>( toupper( static_cast<Byte>( c ) );
}

默认情况下,此函数仅适用于 ASCII 字符(字母 A 到 Z(,因为它采用 C 级区域设置指定的编码,并且默认情况下"C",基本上仅限于 ASCII。但至少它避免了未定义的行为。因此,让我们假设您的示例使用它,

for( auto& c : str ) c = to_upper( c );

这是一个基于范围的循环for它贯穿str中的所有项目,将引用c绑定到每个项目,并执行循环体,该绑定生效。由于str的项目是char型,auto将被推导出为char。所以这和写for( char& c : str ) ...一样.

因此,默认情况下,它将str中的所有ASCII字符大写。

在 Windows 中,如果C 语言环境是通过setlocale( LC_ALL, "" )设置的,则假定的编码将是 Windows ANSI,如果str包含具有该编码的字符,则to_upper将正确完成其大写工作。这意味着在Windows中,可以使用它来例如大写的挪威字符串,如"Blåbærsyltetøy",前提是Windows的语言环境是使用Windows ANSI Western的区域设置。

在 *nix 中,调用setlocale没有帮助,因为用户的本机语言环境将指定 UTF-8 编码,其中 ASCII 之外的每个字符表示为 127>两个或多个字节。

auto & c等效于char & c,它是对字符串中每个字符的引用。更新引用的值会更改字符串中的引用字符。

上述代码的结果将是大写字符串。

最新更新