C ++中的固定宽度整数文字? [英] Fixed-width integer literals in C++?

查看:103
本文介绍了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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆