Как работает тип вывода "auto" и вызов по ссылке? - PullRequest
0 голосов
/ 29 сентября 2018

Как &c работает в этом цикле и при присвоении, c = toupper(c)?

string str = "hello";

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

Не могли бы вы объяснить?

Ответы [ 2 ]

0 голосов
/ 29 сентября 2018

Во-первых, обратите внимание, что 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 ) ....

. Таким образом, по умолчанию он прописывает все символы ASCII в str.

В 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.

0 голосов
/ 29 сентября 2018

auto & c эквивалентно char & c, который является ссылкой на каждый символ в строке.Обновление значения ссылки изменяет ссылочный символ в строке.

Результатом вышеприведенного кода будет строка в верхнем регистре.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...