Яка мета унарного "+" перед викликом до std :: numeric_limits <неподписаних char> членів?


130

Цей приклад я бачив у документації 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()

Я перевірив її, замінив на "-", і це теж спрацювало. Яке використання такого оператора "+"?


3
Спробуй це. Що ви отримуєте, якщо залишите їх +?
Піт Бекер

4
Це питання не потрібно ставити перед собою, якщо письменник коду піклується пояснити, що це означає, або використовувати натомість
чіткий ролик

якщо ви заміните, -тоді виходи не будуть правильними значеннями для обмежень
phuclv

1
Для запису, якщо ви хочете в Google подібну річ в собі, це називається оператором "унар плюс" - це одинарне, оскільки воно приймає єдине значення (в даному випадку річ одразу після нього) і "плюс "- це дружній спосіб Google сказати +. У цьому випадку ваш запит, ймовірно, буде "c ++ unry plus". Це ... не зовсім інтуїтивно зрозуміло, і вам все одно доведеться навчитися читати документацію, яку ви знайдете, але ІМО - це корисна навичка для вирощування.
Моніки

Відповіді:


137

Оператор виводу <<при передачі char(з підписом або без підпису) запише його як символ .

Ці функції повернуть значення типу unsigned char. І як зазначалося вище, що будуть друкувати символи, які ці значення представляють у поточному кодуванні, а не їх цілі значення.

В +операторі перетворює unsigned charповертається ці функції до intчерез просування цілого . Це означає, що замість цього буде надруковано цілі значення.

Вираз на зразок +std::numeric_limits<unsigned char>::lowest()по суті дорівнює static_cast<int>(std::numeric_limits<unsigned char>::lowest()).


37

+є, щоб перетворити unsigned charна int. +Оператор значення збереження, але вона має ефект індукції інтегрального просування на операнде. Потрібно переконатися, що ви бачите числове значення замість якогось (напів-) випадкового символу, який operator <<би надрукувався, коли йому було надано тип символу.


18

Просто додати посилання на вже дані відповіді. Зі стандартним робочим проектом CPP N4713 :

8.5.2.1 Одинарні оператори
...

  1. Операнд оператора unary + повинен мати арифметичний, нескопаний перелік чи тип вказівника, а результат - значення аргументу. Інтегральне просування здійснюється на інтегральних або перелічувальних операндах. Тип результату - тип рекламованого операнда.

І char, short, intі longє невід'ємними типами.


12

Без +результату буде іншим. Наступні фрагменти виходять a 97замістьa a

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також працюватиме

Є багато людей, які зіткнулися з цією проблемою на подібному рівні


1
Ви мали на увазі одинарний плюс , а не мінус?
Руслан
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.