Search code examples
c++c++14c++17lvalueuser-defined-literals

Non-string literals are prvalues?


I'm not sure if I'm missing something, but, user-defined literals, which invokes user-defined functions that could return anything, are also a kind of literals.

The standard says that a literal is always a prvalue, unless it is a string literal, but:

#include <iostream>
#include <typeinfo>

int& operator""_a(unsigned long long c);

int main()
{
    std::cout << std::is_same<decltype(5_a), int&>::value;
} 

prints 1 in both GCC and Clang, which proofs that the literal 5_a (which is not a string literal) is being treated as a lvalue instead of an rvalue:

[expr.prim.literal]/1 A literal is a primary expression. Its type depends on its form. A string literal is an lvalue; all other literals are prvalues.

and user-defined literals are literals too.

What is what I'm missing?


Solution

  • Yes, this is a minor wording defect in the standard. You can find that sentence (nearly) unchanged all the way back in N1905:

    A literal is a primary expression. Its type depends on its form (2.13). A string literal is an lvalue; all other literals are rvalues.

    This standard predates user-defined literals by a few years (N2765 is from mid-2008), and this particular wording wasn't change to reflect that the "all other literals are [p]rvalues" part shouldn't include user-defined literals.

    However, it's pretty clear that since a user-defined-literal is simply syntax sugar for a function call, its value category should be derived from the function call as well. That's the point of the language feature. There's no confusion that the value category of 5_a in your example is lvalue and not prvalue (all compilers agree), so a defect report for this wording would get pretty low precedence, if any.