Какова цель унарного "+" перед вызовом std :: numeric_limits <unsigned char> Члены?
Я видел этот пример в документации cppreference для std::numeric_limits
#include <limits>
#include <iostream>
int main()
{
std::cout << "type\tlowest()\tmin()\t\tmax()\n\n";
std::cout << "uchar\t"
<< +std::numeric_limits<unsigned char>::lowest() << '\t' << '\t'
<< +std::numeric_limits<unsigned char>::min() << '\t' << '\t'
<< +std::numeric_limits<unsigned char>::max() << '\n';
std::cout << "int\t"
<< std::numeric_limits<int>::lowest() << '\t'
<< std::numeric_limits<int>::min() << '\t'
<< std::numeric_limits<int>::max() << '\n';
std::cout << "float\t"
<< std::numeric_limits<float>::lowest() << '\t'
<< std::numeric_limits<float>::min() << '\t'
<< std::numeric_limits<float>::max() << '\n';
std::cout << "double\t"
<< std::numeric_limits<double>::lowest() << '\t'
<< std::numeric_limits<double>::min() << '\t'
<< std::numeric_limits<double>::max() << '\n';
}
Я не понимаю оператора "+" в
<< +std::numeric_limits<unsigned char>::lowest()
Я протестировал его, заменил его на "-", и это тоже сработало. Что такое такой оператор "+"?
Ответы
Ответ 1
Оператор вывода <<
при передаче char
(подписанный или без знака) будет записывать его как символ.
Эта функция вернет значения типа unsigned char
. И, как отмечено выше, будут напечатаны символы, которые эти значения представляют в текущей кодировке, а не их целые значения.
Оператор +
преобразует unsigned char
возвращаемый этими функциями, в int
через целую рекламу. Это означает, что вместо этого будут напечатаны целочисленные значения.
Выражение типа +std::numeric_limits<unsigned char>::lowest()
по существу равно static_cast<int>(std::numeric_limits<unsigned char>::lowest())
.
Ответ 2
+
чтобы включить unsigned char
в int
. Оператор +
сохраняет значение, но он имеет эффект индуцирования цельной рекламы на его операнде. Он должен убедиться, что вместо некоторого (semi-) случайного символа, который operator <<
будет печатать, если задан тип символа, вы увидите числовое значение.
Ответ 3
Просто добавьте ссылку на уже предоставленные ответы. Из стандартного рабочего документа CPP N4713:
8.5.2.1 Унарные операторы
...
- Операнд унарного + оператора должен иметь арифметическое, неперечисленное перечисление или тип указателя, а результат - значение аргумента. Интегральное продвижение выполняется на интегральных или перечисляющих операндах. Тип результата - тип продвинутого операнда.
И char
, short
, int
и long
являются интегральными типами.
Ответ 4
Без +
результат будет другим. Следующий фрагмент выводит a 97
вместо aa
char ch = 'a';
std::cout << ch << ' ' << +ch << '\n';
Причина в том, что разные перегрузки печатают разные типы данных. Нет basic_ostream& operator<<( char value );
перегрузка для std::basic_ostream
и это объясняется в конце страницы
Символьные и символьные строковые аргументы (например, типа char
или const char*
) обрабатываются не-членными перегрузками operator<<
. Попытка вывода символа с использованием синтаксиса вызова функции-члена (например, std::cout.operator<<('c');
) вызовет одну из перегрузок (2-4) и выведет числовое значение. Попытка вывода символьной строки с использованием синтаксиса вызова функции-члена вызовет перегрузку (7) и вместо этого напечатает значение указателя.
Не-членная перегрузка, которая будет вызываться при передаче переменной char
template< class CharT, class Traits> basic_ostream<CharT,Traits>& operator<<(
basic_ostream<CharT,Traits>& os, char ch );
который печатает символ в кодеке ch
Так что в основном, если вы передаете char
, signed char
или unsigned char
непосредственно в поток, он выведет символ. Если вы попытаетесь удалить символ +
в приведенных выше строках, вы увидите, что он печатает некоторые "странные" или невидимые символы, что не следует ожидать
Если вам нужны их числовые значения, вы должны вызвать перегрузку для short
, int
, long
или long long
. Самый простой способ сделать это - продвигать от char
до int
с унарным плюсом +
. Это одно из редких полезных приложений унарного оператора. Явное преобразование в int
также будет работать
Есть много людей, которые столкнулись с этой проблемой на SO like