Универсальная система счисления преобразование в десятичную с помощью UDL - PullRequest
3 голосов
/ 09 мая 2019

Я пытаюсь создать универсальную функцию преобразования, которая нацелена на преобразование любой системы счисления в десятичную систему:

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~F: int a = 82ABC_H, и выдает ошибку типа: invalid digit A in decimal constant

живая демоверсия

Конечно, я могу использовать operator ""_H(const char*, std::size_t) для системы счисления с базой> 10, но она не может повторно использовать мою toDecImpl, если я не напишу другую для этих систем счисления.

Вопрос: Есть ли здесь какой-нибудь элегантный обходной путь для повторного использования toDecImpl для системы счисления, содержащей альфа-подобный гекс?

1 Ответ

0 голосов
/ 09 мая 2019

Если я правильно понял ваше определение «элегантный», Нет, это невозможно. Пользовательский литерал не может изменить синтаксис. За [lex.icon] , Вы можете использовать 0x или 0X с шестнадцатеричными цифрами, или вы можете использовать только десятичные цифры без 0x или 0X. Компилятор проверяет это перед передачей фактического содержимого в функцию UDL.

Да, конечно, вы можете использовать строковые литералы. Это должно быть приемлемым решением в этом случае.

...