【问题标题】:Fixed-width integer literals in C++?C ++中的固定宽度整数文字?
【发布时间】:2016-07-24 05:05:06
【问题描述】:

C++11 首次通过用户定义的文字引入了对在 C++ 中定义新文字的支持。 C++11 或更高版本是否还为 <cstdint> 中的类型预定义了固定宽度整数文字的后缀?

【问题讨论】:

    标签: c++ c++11 language-lawyer c++14 user-defined-literals


    【解决方案1】:

    否。 从 C++14 开始,标准定义的唯一文字后缀由标准库中的 <chrono><complex><string> 标头提供。 <chrono> 标头定义了hminsmsusns 持续时间的后缀,<complex> 定义了@9876543365@、@98744365@、@98764 @ 后缀表示虚数,<string> 定义 s 后缀表示 basic_string 文字。

    但是,可以像这样轻松定义自己的固定宽度文字:

    #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_int8better implementation(GPL-3 许可)可能必须逐个字符地解析文字,并在溢出时解析 static_assert,例如 this

    使用用户定义文字的缺点是需要在后缀前加上下划线 _,因为根据 §17.6.4.3.4 保留不带下划线的后缀以供将来标准化。

    猜你喜欢
    • 1970-01-01
    • 2010-09-25
    • 1970-01-01
    • 2010-12-16
    • 1970-01-01
    • 1970-01-01
    • 2012-05-29
    • 1970-01-01
    相关资源
    最近更新 更多