Мне интересно, почему я не могу написать такой код:
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
Это может быть проблемой лексера. Пользовательский литерал должен быть токенизирован как один кусок — число плюс суффикс — это один целый токен. В случае числовых литералов символы, которым разрешено выплескивать, включают десятичную дробь ‘.’. Поиск 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...
В этот момент остаток от «-» передается как идентификатор суффикса.
Помните, что числовые литералы интерпретируются после препроцессор токенизирует.
Я думаю, что это на самом деле не дефект
Предполагается, что суффиксом для UDL является нормальный идентификатор (с начальным подчеркиванием), поэтому для меня это выглядит как ошибка.