2016-04-04 16 views
10

C++ 11 supporto introdotto per la prima volta per la definizione di nuovi letterali in C++ mediante valori letterali definiti dall'utente . C++ 11 o versioni successive predefiniscono anche i suffissi per valori letterali interi a larghezza fissa per i tipi in <cstdint>?Letterali interi a larghezza fissa in C++?

risposta

9

No. Come di C++ 14 i soli suffissi letterali definito dallo standard sono fornite da <chrono>, <complex> e <string> intestazioni nella libreria standard. L'intestazione <chrono> definisce il h, min, s, ms, us, ns suffissi per durate di tempo, <complex> definisce le i, il e if suffissi dei numeri immaginari, e <string> definisce il suffisso s per basic_string letterali.

Tuttavia, si può facilmente definire i propri valori letterali a larghezza fissa come questo:

#include <cstdint> 

constexpr std::int8_t operator "" _int8(unsigned long long v) 
{ return static_cast<std::int8_t>(v); } 

constexpr std::uint8_t operator "" _uint8(unsigned long long v) 
{ return static_cast<std::uint8_t>(v); } 

constexpr std::int16_t operator "" _int16(unsigned long long v) 
{ return static_cast<std::int16_t>(v); } 

constexpr std::uint16_t operator "" _uint16(unsigned long long v) 
{ return static_cast<std::uint16_t>(v); } 

constexpr std::int32_t operator "" _int32(unsigned long long v) 
{ return static_cast<std::int32_t>(v); } 

constexpr std::uint32_t operator "" _uint32(unsigned long long v) 
{ return static_cast<std::uint32_t>(v); } 

constexpr std::int64_t operator "" _int64(unsigned long long v) 
{ return static_cast<std::int64_t>(v); } 

constexpr std::uint64_t operator "" _uint64(unsigned long long v) 
{ return static_cast<std::uint64_t>(v); } 

constexpr std::int_fast8_t operator "" _int_fast8(unsigned long long v) 
{ return static_cast<std::int_fast8_t>(v); } 

constexpr std::uint_fast8_t operator "" _uint_fast8(unsigned long long v) 
{ return static_cast<std::uint_fast8_t>(v); } 

constexpr std::int_fast16_t operator "" _int_fast16(unsigned long long v) 
{ return static_cast<std::int_fast16_t>(v); } 

constexpr std::uint_fast16_t operator "" _uint_fast16(unsigned long long v) 
{ return static_cast<std::uint_fast16_t>(v); } 

constexpr std::int_fast32_t operator "" _int_fast32(unsigned long long v) 
{ return static_cast<std::int_fast32_t>(v); } 

constexpr std::uint_fast32_t operator "" _uint_fast32(unsigned long long v) 
{ return static_cast<std::uint_fast32_t>(v); } 

constexpr std::int_fast64_t operator "" _int_fast64(unsigned long long v) 
{ return static_cast<std::int_fast64_t>(v); } 

constexpr std::uint_fast64_t operator "" _uint_fast64(unsigned long long v) 
{ return static_cast<std::uint_fast64_t>(v); } 

constexpr std::int_least8_t operator "" _int_least8(unsigned long long v) 
{ return static_cast<std::int_least8_t>(v); } 

constexpr std::uint_least8_t operator "" _uint_least8(unsigned long long v) 
{ return static_cast<std::uint_least8_t>(v); } 

constexpr std::int_least16_t operator "" _int_least16(unsigned long long v) 
{ return static_cast<std::int_least16_t>(v); } 

constexpr std::uint_least16_t operator "" _uint_least16(unsigned long long v) 
{ return static_cast<std::uint_least16_t>(v); } 

constexpr std::int_least32_t operator "" _int_least32(unsigned long long v) 
{ return static_cast<std::int_least32_t>(v); } 

constexpr std::uint_least32_t operator "" _uint_least32(unsigned long long v) 
{ return static_cast<std::uint_least32_t>(v); } 

constexpr std::int_least64_t operator "" _int_least64(unsigned long long v) 
{ return static_cast<std::int_least64_t>(v); } 

constexpr std::uint_least64_t operator "" _uint_least64(unsigned long long v) 
{ return static_cast<std::uint_least64_t>(v); } 

constexpr std::intmax_t operator "" _intmax(unsigned long long v) 
{ return static_cast<std::intmax_t>(v); } 

constexpr std::uintmax_t operator "" _uintmax(unsigned long long v) 
{ return static_cast<std::uintmax_t>(v); } 

constexpr std::intptr_t operator "" _intptr(unsigned long long v) 
{ return static_cast<std::intptr_t>(v); } 

constexpr std::uintptr_t operator "" _uintptr(unsigned long long v) 
{ return static_cast<std::uintptr_t>(v); } 

Attenzione: Il codice qui sopra in silenzio di dare il risultato di male se usato su letterali che non rientrano in unsigned long long , così come overflow se il valore letterale, non si adatta al tipo richiesto, ad es 999_int8. Un better implementation (con licenza GPL-3) probabilmente dovrebbe analizzare il carattere letterale per carattere e lo static_assert in overflow, come this.

Lo svantaggio dell'utilizzo di valori letterali definiti dall'utente è che è necessario anteporre i suffissi a un trattino di sottolineatura _, poiché i suffissi senza il carattere di sottolineatura sono riservati per la futura standardizzazione in base a §17.6.4.3.4.

+0

Che dire di [lanciare un'eccezione su overflow, rendendo fallita la compilazione] (http://stackoverflow.com/a/8626450/256138)? – rubenvb