Peregring-lk Peregring-lk - 1 year ago 83
C++ Question

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?

Answer Source

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.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download