推理类型如何工作"auto"和按引用调用?
How type Inference "auto" and call by reference works?
&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
,它是对字符串中每个字符的引用。更新引用的值会更改字符串中的引用字符。
上述代码的结果将是大写字符串。
- 为什么当我为 for(auto& it : myUnorderedMap) {... = std::move(it.second)} 时,我会得到一个 const 引用?
- 为什么结构化绑定不使用"auto&"返回对结构成员的引用,而是返回成员本身
- 推理类型如何工作"auto"和按引用调用?
- C++/11 auto 关键字是在更有效时推导参数进行按引用传递,还是始终按值传递?
- 为什么"const auto [x, y]"绑定到引用类型时没有按预期运行?
- 如果使用返回引用的函数初始化"auto"var,为什么它不声明引用类型?
- 提示编译器在使用 auto 时通过引用返回,而不使用 ->
- 为什么在使用 auto&&it=--vec.end(),是 UB 时自动推导左值引用?
- 如何验证返回的“auto”变量是否为引用
- 从函数返回引用是否会导致在使用'auto'时创建新的临时对象?
- C++11:常量和引用类型上“auto”操作的标准引用
- 具有代理迭代器/引用和auto的容器
- 当 auto 的初始值设定项是引用时,为什么它不是引用
- auto&& 变量不是右值引用
- 强制auto为range for循环中的引用类型
- 将非const引用使用auto-keyword声明的lambda作为实参传递给std::函数形参类型
- Decltype (auto) foo()返回本地引用,没有任何警告
- C++11 auto:如果它得到一个常量引用怎么办
- 当 auto 用于数组时,为什么它被转换为指针而不是引用?
- const-static auto lambda与引用捕获一起使用