Почему пользовательские строковые литералы и целочисленные литералы имеют другое поведение?

Я узнаю о пользовательских литералах и путаюсь со следующим тестовым кодом:

std::chrono::seconds operator"" _s(unsigned long long s) { return std::chrono::seconds(s); } std::string operator"" _str(const char *s, std::size_t len) { return std::string(s, len); } int main() { auto str = "xxxxx"_str; std::cout << str.size() << std::endl; // works auto sec = 4_s; std::cout << sec.count() << std::endl; // works std::cout << "xxxxx"_str.size() << std::endl; // works std::cout << 4_s.count() << std::endl; // does **NOT** work! return 0; } 

Компилятор сообщает следующее сообщение об ошибке:

error: нет соответствующего оператора literal для вызова «operator» «_s.count» с аргументом типа «unsigned long long» или «const char *» и без соответствующего шаблона оператора литерала
cout << 4_s.count () << endl;

Кажется, что он принимает _s.count как пользовательский литерал. Кроме того, литерал с плавающей запятой ведет себя как целочисленный литерал.

Почему пользовательские целые литералы и строковые литералы имеют другое поведение?

Вот как работают литералы с плавающей запятой !

Добавьте пару круглых скобок, и она должна работать:

 std::cout << (4_s).count(); 

Или, наоборот, отделите их (чтобы остановить компилятор от интерпретации его как плохо сформированного дробного постоянного литерала с плавающей запятой):

 std::cout << 4_s .count(); // ^ Space here! 

Ссылка: CppReference.com

В разделе « Примечания » выше,

Из-за максимального munch пользовательские целые и литералы с плавающей запятой, заканчивающиеся на [ p , P , (начиная с C ++ 17)] e и E , после которых следуют операторы + или - , должны быть отделены от оператора пробелами в источник:

 long double operator""_E(long double); long double operator""_a(long double); int operator""_p(unsigned long long); auto x = 1.0_E+2.0; // error auto y = 1.0_a+2.0; // OK auto z = 1.0_E +2.0; // OK auto w = 1_p+2; // error auto u = 1_p +2; // OK 

Поэтому, когда дело доходит до точки, которая используется как десятичная точка , она должна быть отделена от чего-либо позади или будет рассматриваться как часть числа с плавающей запятой .

Я проверил приведенный выше пример из CppReference и получил сообщение об ошибке силимара:

 test.cpp:19:10: error: unable to find numeric literal operator 'operator""_E+2.0' ^^^^^^ auto x = 1.0_E+2.0; // error 

Понял, как _E+2.0 рассматривается как целой ud-суффикс ?


Мое первоначальное объяснение можно найти в истории изменений этого сообщения.