Какова цель унарного "+" перед вызовом 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 Унарные операторы
...

  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