I'm learning about user-defined literals, and confused with the following test code:
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;
}
The compiler gives the following error message:
error: no matching literal operator for call to 'operator""_s.count' with argument of type 'unsigned long long' or 'const char *', and no matching literal operator template
cout << 4_s.count() << endl;
It seems that it takes _s.count as a user-defined literal. Also, a floating-point literal behaves like an integer literal.
Why do user-defined integer literals and string literals have different behavior?
(4_s).count
works. You CANNOT have(
or)
in theud-suffix
. – Aspirator.
could not be used inud-suffix
either; can't get why_s.count
is parsed as the wholeud-suffix
. – Underclothing4_s.count
is parsed as a preprocessing number token, which is tolerated by the preprocessor and is converted to a token after preprocessing but before syntactic and semantic analysis, but it can't be converted to a valid token (e.g. interger literal or floating literal), and thus violates [lex.pptoken]/1. Admittedly the compiler error is totally unhelpful in this case. – Mulligatawny