通用数字系统使用udl转换为十进制

时间:2019-05-09 07:07:28

标签: c++ c++17 user-defined-literals number-systems

我正在尝试创建一个通用转换函数,该函数旨在将任何基数的数字系统转换为十进制:

namespace detail
{
    template<char Chs> constexpr auto
    toDecImpl()
    {
        return Chs > '9' ? Chs - 'A' + 10 : Chs - '0';
    }
} // namespace detail
template<int from, char... Chs> constexpr auto
toDec()
{
    int ret{};

    return ((ret *= from, ret += detail::toDecImpl<Chs>()), ...);
}

用例如下:

inline namespace literals
{
    template<char... Chs> constexpr auto
    operator"" _B()
    {
        return toDec<2, Chs...>();
    }
    template<char... Chs> constexpr auto
    operator"" _O()
    {
        return toDec<8, Chs...>();
    }
    template<char... Chs> constexpr auto
    operator"" _H()
    {
        return toDec<16, Chs...>();
    }
}

至于十六进制,其中包含非数字字符,如A~Fint a = 82ABC_H,它将给出类似invalid digit A in decimal constant

的错误

live demo

当然,我可以将operator ""_H(const char*, std::size_t)用于基数为10的数字系统,但是除非我为这些数字系统编写另一个数字,否则它不能重用我的toDecImpl

问题:这里是否有任何优雅的解决方法可将toDecImpl重新用于包含十六进制等字母的数字系统?

1 个答案:

答案 0 :(得分:0)

如果我正确理解了您对“优雅”的定义, 不,这是不可能的。 用户定义的文字不能更改语法。 根据{{​​3}}, 您可以将0x0X与十六进制数字一起使用, 或者您只能使用不带0x0X的十进制数字。 编译器会在将实际内容提供给UDL函数之前进行检查。

是的,您当然可以使用字符串文字。 在这种情况下,这应该是可以接受的解决方法。