Разрешены ли 14-значные разделители C ++ в пользовательских литералах?

В то время как clang компилирует следующую строку, g ++ 6.1 жалуется на разделитель цифр (см. живой пример на колиру):

auto time = 01'23s;

Какой компилятор, если таковой имеется, является правильным в соответствии со стандартом C ++ 14 (N3796)?

В противном случае разрешается использование разделителей цифр (§2.14.2) только в деталях реализации пользовательских литералов (§2.14.8) <chrono> библиотека (§20.12.5.8)? ИМХО так быть не должно, так как эти литералы определены на unsigned long long параметры.

Я помню, как Говард Хиннант использовал 10'000s в качестве примера во время его CppCon 2016 talk «A <chrono> руководство» (около 42 минут в его разговоре).


(Обратите внимание, что я не собирался кодировать «1 минуту и ​​23 секунды», то есть только правильно случайно, поскольку восьмеричный литерал 0123 равен 64 + 16 + 3 == 83. Для этого я должен написать

auto time = 1min + 23s;

но это возможное вводящее в заблуждение толкование не является частью вопроса.)

42

Решение

Если вы посмотрите на грамматику, определяемый пользователь целочисленного-буквальная может быть восьмерично-буквальный ud-суффикс, а также восьмеричный литерал определяется как либо 0 или же восьмерично-буквальныйвыбирать восьмеричное-значный.

N4140 §2.14.8

определяемый пользователь-буквальный:

  • определяемый пользователь целочисленного-буквальная
  • […]

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

  • восьмерично-буквальный ud-суффикс
  • […]

N4140 §2.14.2

восьмеричный литерал:

  • 0
  • восьмерично-буквальныйвыбирать восьмеричное-значный

Так 01'23s это совершенно действительный литерал.

19

Другие решения

WLOG для десятичных литералов:

[Lex.ext]:

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

[словарный запас]:

десятичный литерал:
    ненулевая цифра
    десятичный литерал  выбирать 
цифра

То есть да, в UDL допускаются разделители цифр.

5

Это похоже на ошибку в реализации GCC <chrono> библиотека, как предложил Аарон МакДейд. Существует (в настоящее время неподтвержденное) сообщение об ошибке: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69905

Libstdc ++ GCC реализует две подписи для std::chrono_literals:

constexpr chrono::duration<long double>
operator""s(long double __secs)
{ return chrono::duration<long double>{__secs}; }

template <char... _Digits>
constexpr chrono::seconds
operator""s()
{ return __check_overflow<chrono::seconds, _Digits...>(); }

Версия шаблона с ошибкой не требуется стандартом.
При добавлении

constexpr chrono::seconds
operator""s(unsigned long long __secs)
{ return chrono::seconds{__secs}; }

к <chrono> заголовок (моей локальной установки) ошибка исчезает.

Однако разработчики библиотеки GCC могли специально исключить эту версию, чтобы они могли предотвратить нежелательное преобразование неподписанных в подписанные, поскольку секунды определены как

typedef duration<int64_t> seconds;

Редактировать:

Как недавно отметил Джонатан Уэйкли в комментариях к сообщению об ошибке,
реализация была выбрана по проекту в связи с
вопрос открытой рабочей группы библиотеки, но не принял во внимание разделители цифр.

5
По вопросам рекламы [email protected]