C ++中的固定宽度整数文字? [英] Fixed-width integer literals in C++?
问题描述
C ++ 11首先引入了通过用户定义文字将新文字定义为C ++的支持。 C ++ 11或更高版本还为< cstdint>
类型的固定宽度整型字面量预定义了后缀 从C ++ 14开始,标准定义的字面后缀由
< chrono>
,< complex>
和< string>
< chrono>
标题定义 h
, min
, s
, ms
, us
, ns
定义 i
code> il 和 if
虚数的后缀,< string>
为 basic_string
文字定义 s
后缀。 但是,可以很容易地定义自己的固定宽度文字,例如:
#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) }
警告:如果使用上述代码,对于不适合 unsigned long long
的文字,以及如果文字值不符合请求类型的溢出,例如 999_int8
。 更好的实施(GPL-3许可)可能必须在溢出时解析字面字符和 static_assert
,例如 this 。
使用用户定义文字的缺点是需要在后缀前缀带有下划线 _
,因为没有下划线的后缀保留用于根据§17.6.4.3.4的未来标准化。
C++11 first introduced support for defining new literals into C++ by means of user-defined literals. Does C++11 or later also predefine suffixes for fixed-width integer literals for types in <cstdint>
?
No. As of C++14 the only literal suffixes defined by the standard are provided by <chrono>
, <complex>
and <string>
headers in the standard library. The <chrono>
header defines the h
, min
, s
, ms
, us
, ns
suffixes for time durations, <complex>
defines the i
, il
and if
suffixes for imaginary numbers, and <string>
defines the s
suffix for basic_string
literals.
However, one can easily define their own fixed-width literals like this:
#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); }
Warning: The above code will silently give the wrong result if used on literals which don't fit into unsigned long long
, as well as overflow if the literal value, doesn't fit into the requested type, e.g. 999_int8
. A better implementation (GPL-3 licensed) would probably have to parse the literal character-by-character and static_assert
on overflow, like this.
The downside of using user defined literals is that one needs to prefix the suffixes with an underscore _
, because suffixes without the underscore are reserved for future standardization according to §17.6.4.3.4.
这篇关于C ++中的固定宽度整数文字?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!