Як написати короткий буквальний текст на C ++?


120

Дуже основне запитання: як мені написати shortбуква в C ++?

Я знаю наступне:

  • 2 є int
  • 2U є unsigned int
  • 2L це long
  • 2LL це long long
  • 2.0f це float
  • 2.0 це double
  • '\2'є а char.

Але як би я написав shortбуквальне? Я спробував, 2Sале це дає попередження компілятора.


10
Я вважаю, що короткий літерал не підтримується виключно через те, що нічого менше, ніж int, буде "підвищено" до int під час оцінки. int має найбільш природний розмір. Це називається цілим просуванням в C ++.
користувач534498

Відповіді:


82
((short)2)

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

Це я робив, бо нічого не міг знайти про це. Я б припустив, що компілятор буде досить розумним, щоб скомпілювати це так, як якщо б це був короткий літерал (тобто він насправді не виділяв би int, а потім передавав його кожен раз).

Далі показано, як сильно ви повинні турбуватися з цього приводу:

a = 2L;
b = 2.0;
c = (short)2;
d = '\2';

Складіть -> розібрати ->

movl    $2, _a
movl    $2, _b
movl    $2, _c
movl    $2, _d

Це я робив, бо нічого не міг знайти про це. Я б здогадався, що компілятор був би досить розумним, щоб скомпілювати це так, ніби це короткий літерал (тобто він насправді не виділяє int, а потім передаватиме його кожен раз).
Кіп

"Акторський склад" насправді нічого не робить. Коли ми говоримо на C або C ++ (інструкція асемблера "не вводиться" (.NET MSIL - це інша історія). Там, на металі, все це лише двійкові цифри
Ісак Саво

9
Які вище типи a, b, c і d?
Атес Горал

2
@Ates Goral: Усі вклад. Зміна на короткий або char може, мабуть, змінити інструкцію movw або movb через дошку.

2
Це не короткий літерал. Коли ви використовуєте цей склад і компіляцію з GCC та опцією -Wconversion, ви все одно отримуєте діагностику компілятора для оператора short foo = 1; foo += (short)2;. Але цього не можна обійти через ціле просування.
harper

51

C ++ 11 дає вам близько до того, що ви хочете. (Шукайте "визначені користувачем літерали", щоб дізнатися більше.)

#include <cstdint>

inline std::uint16_t operator "" _u(unsigned long long value)
{
    return static_cast<std::uint16_t>(value);
}

void func(std::uint32_t value); // 1
void func(std::uint16_t value); // 2

func(0x1234U); // calls 1
func(0x1234_u); // calls 2

// also
inline std::int16_t operator "" _s(unsigned long long value)
{
    return static_cast<std::int16_t>(value);
}

6
shortфізично не може бути std::uintнічого, оскільки це підписаний тип. І не потрібно бути 16 бітами або тим же типом, що і std::int16_t..., який сам по собі навіть не вимагає існування в даній реалізації, якщо платформа не може надати тип точної ширини. Основна ідея цієї відповіді є хорошою, але вона знецінюється незрозумілою дотичною на неспоріднені типи, про які ОП не запитувала.
підкреслити_

Зверніть увагу, визначені користувачем літерали не підтримуються у Visual Studio до VS2015: msdn.microsoft.com/en-us/library/hh567368(v=vs.140).aspx
parsley72

Я не знаю, чи варто мені це любити чи ненавидіти, але це останній фрагмент моєї фактично сильної цілочисельної системи типу C ++, над якою я працюю.
Sahsahae

echoing @underscore_d, я б подав пропозицію, але після редагування, shortяк це зроблено в ОП.
v.oddou

28

Навіть письменники стандарту C99 зловили це. Це фрагмент з stdint.hреалізації публічного надбання Денні Сміта :

/* 7.18.4.1  Macros for minimum-width integer constants

    Accoding to Douglas Gwyn <gwyn@arl.mil>:
    "This spec was changed in ISO/IEC 9899:1999 TC1; in ISO/IEC
    9899:1999 as initially published, the expansion was required
    to be an integer constant of precisely matching type, which
    is impossible to accomplish for the shorter types on most
    platforms, because C99 provides no standard way to designate
    an integer constant with width less than that of type int.
    TC1 changed this to require just an integer constant
    *expression* with *promoted* type."
*/

18

Якщо ви використовуєте Microsoft Visual C ++, для кожного цілого типу доступні буквальні суфікси:

auto var1 = 10i8;  // char
auto var2 = 10ui8; // unsigned char

auto var3 = 10i16;  // short
auto var4 = 10ui16; // unsigned short

auto var5 = 10i32;  // int
auto var6 = 10ui32; // unsigned int

auto var7 = 10i64;  // long long
auto var8 = 10ui64; // unsigned long long

Зауважте, що це нестандартне розширення і не є портативним . Насправді я навіть не міг знайти жодної інформації про ці суфікси в MSDN.


1
Коли ви відстежите один із суфіксів, ви побачите, що напр. ""ui8Визначається як '\000', що по суті є '\0'.
Микита

10

Ви також можете використовувати синтаксис псевдоконструктора.

short(2)

Я вважаю це більш читабельним, ніж кастинг.


4
це називається "функціональним виразним складом". Мені це дуже подобається, особливо при програмуванні за допомогою Windows API.
klaus triendl

6

Наскільки я знаю, ви не знаєте, такого суфіксу немає. Більшість компіляторів попередить, чи не є цілий літерал занадто великим, щоб вмістити будь-яку змінну, в якій ви намагаєтеся зберігати його.

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