Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Combining a user defined literal with a method call

I'm wondering why I can't write code like this:

constexpr double radius = 27_km.to_miles(); // _km returns Distance instance 
                                            // which has to_miles()

Both GCC 4.8.1 and Clang 3.4 complain that they couldn't find literal operator operator"" _km.to_miles unless I wrap 27_km in parentheses:

constexpr double radius = (27_km).to_miles(); // fine

By my reading of section 2.14.8 of the standard, a UDL suffix can't contain a period, so why are the compilers parsing the code like this? Are they correct or is it a bug?

EDIT: You can see a full example (with different UDL and method names) here: http://ideone.com/rvB1pk

like image 849
Alex Korban Avatar asked Oct 16 '13 03:10

Alex Korban


People also ask

What is a user-defined literal?

In source code, any literal, whether user-defined or not, is essentially a sequence of alphanumeric characters, such as 101 , or 54.7 , or "hello" or true . The compiler interprets the sequence as an integer, float, const char* string, and so on.

What is a user-defined literal C++?

A literal is used for representing a fixed value in a program. A literal could be anything in a code like a, b, c2. , 'ACB', etc. Similarly, User-Defined Literals (UDL) provides literals for a variety of built-in types that are limited to integer, character, floating-point, string, boolean, and pointer.

What is difference between constants and literals?

A literal is a value that is expressed as itself. For example, the number 25 or the string "Hello World" are both literals. A variable in a program can change its value during the course of execution of the program. A constant retains the same value throughout the program.

What is string literal operator?

A string literal or anonymous string is a string value in the source code of a computer program. In modern programming languages usually use a quoted sequence of characters, formally "bracketed delimiters", as in x = "foo" . Where "foo" is a string literal with value foo .


2 Answers

The suffix for a UDL is supposed to be a normal identifier (with a leading underscore), so it looks like a bug to me.

like image 67
Jerry Coffin Avatar answered Oct 12 '22 23:10

Jerry Coffin


This may be a lexer issue. The user-defined literal is to be tokenized as a single chunk - number plus suffix is one whole token. In the case of numeric literals the characters it is allowed to slurp up includes the decimal '.'. Lookup pp-number: section 2.10 - lex.ppnumber in the latest draft of the standard. Walk through how the preprocessor (lexer) would scan the token:

30_au.to_light_years()

digit
digit
identifier-nondigit
.
identifier-nondigit x 14
( breaks the spell

So the preprocessor sees 30_au.to_light_years as a big freaky (floating-point) number. Then later, during the number parsing phase we see digit, digit, identifier-nondigit... At that point, the remainder from '-' onwards is handed off as a suffix identifier.

Remember that number literals are interpreted after the preprocessor tokenizes.

I think this is actually not a defect.

like image 33
emsr Avatar answered Oct 12 '22 22:10

emsr