Error: unable to find numeric literal operator

Since C++11 we have an option to define our own literals . They look like function calls in disguise but they have some unexpected behaviour. You can for instance write:


constexpr long double operator"" 
_kilometers (long double km) 
{ return km*1000; } // meters

And then you might try to use your new literal as:


double dist1 = 5000_kilometers;
double dist2 = 5000.0_kilometers;

But you are greeted with nice error on first attempt: "unable to find numeric literal operator".

Seems like when my compiler (g++ 4.7.2) encounters a user-defined literal it decides first what the previous token was, only then it searches for the correct overload declaration. For instance, a number 5000 will parse to a user-defined integer literal and compiler will try to find an overload that matches one with integer argument. As double is not an integer type, it will simply fail to find a corresponding overload and complain about it. It will not attempt to convert 5000 to floating-point type just to match it with the user-defined string literal. I am not sure whether this is how it is supposed to work or is this just a feature of my particular compiler.

There are couple of solutions to this. The one I like the most is to simply write .0 after each integer and accept things as they are. I haven't found a way to use both built-in literals, like f for float, and user-defined literals at the same time. Another solution is to define each function twice but each time with different types of arguments. Yet another solution is to do some preprocessor gymnastics. Not really recommended for serious projects because it might confuse other readers of the code, but fun to consider:


/*1234*/#ifndef UNITS_TEST_H
/*12  */  #ifndef UNITS_H_INTEGER_LITERALS
/*1   */    #define UNITS_H_INTEGER_LITERALS
/*1   */    #define NUMERIC_TYPE unsigned long long
/* 2  */  #else
/* 2  */    #undef NUMERIC_TYPE
/* 2  */    #define NUMERIC_TYPE long double
/* 2  */    #defineUNITS_TEST_H
/*12  */  #endif
/*12  */  constexpr long double operator"" _kilometers (NUMERIC_TYPE km) { return km*1000; } // meters
/*12  */  #include "./units_test.h"
/*1234*/#endif// UNITS_TEST_H

Say this code is in a file called units_test.h. When you #include units_test.h it will actualy get included twice in a row. A user-defined literal is defined in a file, but argument to the function is a #define itself. In two passes the preprocessor will create two separate literals definitions, one for each definition of NUMERIC_TYPE. On first pass NUMERIC_TYPE will be defined as an integer type. That will be changed in the second pass, which is triggered by the header file simply including itself again. It is undefined first to avoid warning about multiple definitions of same thing. The numbers in the comments on the left illustrate how subsequent passes go through that same code.


Previous: Debug output from dll
Next: Using smart pointers in building trees in which child nodes need an access to the parent