c++expressionstandardsmember-functionsuser-defined-literals

Why is `""s.size()` legal, but `5ms.count()` is not?


#include <chrono>
#include <string>

using namespace std::literals;

int main() {
    ""s.size();     // ok
    (""s).size();   // ok
    (5ms).count();  // ok
    5ms.count();    // error
}

The error message is:

error: unable to find numeric literal operator 'operator""ms.count'

See https://godbolt.org/z/qT6G1nbzM

Why is ""s.size() legal, but 5ms.count() is not? What is the rationale behind the rules?


Solution

  • Per User defined literals on cppreference:

    Due to maximal munch, user-defined integer and floating point literals ending in p, P (since C++17), e and E, when followed by the operators + or -, must be separated from the operator with whitespace or parentheses in the source

    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 q = (1.0_E)+2.0; // OK
    auto w = 1_p+2;       // error
    auto u = 1_p +2;      // OK
    

    Same applies to dot operator following an integer or floating-point user-defined literal:

    #include <chrono>
    
    using namespace std::literals;
     
    auto a = 4s.count();   // Error
    auto b = 4s .count();  // OK
    auto c = (4s).count(); // OK
    

    Since 5ms is an integer user-defined literal, you then need (5ms).count() or 5ms .count().