Объединение пользовательского литерала с вызовом метода

Мне интересно, почему я не могу написать такой код:

constexpr double radius = 27_km.to_miles(); // _km returns Distance instance
// which has to_miles()

И GCC 4.8.1, и Clang 3.4 жалуются, что не могут найти буквальный оператор operator"" _km.to_miles если я не заверну 27_km в скобках:

constexpr double radius = (27_km).to_miles(); // fine

В моем прочтении раздела 2.14.8 стандарта суффикс UDL не может содержать точку, так почему же компиляторы анализируют такой код? Они правильные или это ошибка?

РЕДАКТИРОВАТЬ: Вы можете увидеть полный пример (с разными UDL и именами методов) здесь: http://ideone.com/rvB1pk

6

Решение

Это может быть проблемой лексера. Пользовательский литерал должен быть токенизирован как один кусок — число плюс суффикс — это один целый токен. В случае числовых литералов символы, которым разрешено выплескивать, включают десятичную дробь ‘.’. Поиск pp-номера: раздел 2.10 — lex.ppnumber в последний проект стандарта. Пройдемся по тому, как препроцессор (лексер) будет сканировать токен:

30_au.to_light_years()

digit
digit
identifier-nondigit
.
identifier-nondigit x 14
( breaks the spell

Итак препроцессор видит 30_au.to_light_years как большой причудливый (с плавающей запятой) число. затем потом, на этапе разбора числа мы видим digit, digit, identifier-nondigit... В этот момент остаток от «-» передается как идентификатор суффикса.

Помните, что числовые литералы интерпретируются после препроцессор токенизирует.

Я думаю, что это на самом деле не дефект

2

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

Предполагается, что суффиксом для UDL является нормальный идентификатор (с начальным подчеркиванием), поэтому для меня это выглядит как ошибка.

3

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