C++11 Tidbits: User-defined Literals

Let's have a look at a nifty small feature, which people learning to program in C++11 will like a lot.

Consider the following self contained program:

   #include <iostream>

   long double operator"" _mm(long double x) { return x / 1000; }
   long double operator"" _m(long double x)  { return x; }
   long double operator"" _km(long double x) { return x * 1000; }

   int main()
   {
     std::cout << 1.0_mm << '\n';
     std::cout << 1.0_m  << '\n';
     std::cout << 1.0_km << '\n';
   }

and its output:

   0.001
   1
   1000

The new syntax should be rather self-explanatory: the first three lines of the code after the #include define three user-defined operators of a new type, called literal operator. In the example, the three operators know the power of ten corresponding to each SI prefix, that is 1 mm = 10^-3 m, 1 km = 10^3 m, plus the trivial 1 m = 1 m, and are thus able to automatically compute how many meters correspond to each SI length.

In order to start experimenting with this feature, it's useful to know that there are restrictions to the number and type of the parameters of the operators. Essentially (see C++11 or N2765 for details) only the following signatures are legal:

   char const*
   unsigned long long
   long double
   char const*, std::size_t
   wchar_t const*, std::size_t
   char16_t const*, std::size_t
   char32_t const*, std::size_t

where the last four are useful for strings because the second argument is automatically deduced as the length of the string. For example:

   std::size_t operator"" _len(char const*, std::size_t l) 
   { 
     return l;
   }

   int main()
   {
     std::cout << "ABCDEFGH"_len << '\n';
   }

gives the output:

   8

The first signature type I listed, not to be confused with the signatures for strings, is used for so-called raw literal operators. For example:

   char const* operator"" _r(char const* s) 
   {
     return s;
   }

   int main()
   {
     std::cout << 12_r << '\n';
   }

which outputs:

   12

The return type of a literal operator, on the other hand, is not restricted. For example it could be a full-fledged class type like std::string:

   std::string operator"" _rs(char const* s)
   { 
     return 'x' + std::string(s) + 'y'; 
   }

   int main()
   {
     std::cout << 5_rs << '\n';
   }

which outputs:

   x5y

As always, if you are looking for rationale, relationships to similar features in other languages, compatibility with C99, and all the technical details which guided the evolution of the facility until the final standardization in C++11, the early discussion papers are very useful, in particular N1892, in 2005.

User-defined literals are brand new in GCC. Thus, if you are interested in experimenting, a mainline snapshot or a tree checked out via SVN is necessary. On the other hand, you have a chance to help the project to fixing the remaining bugs. In any case the release of 4.7.0 is very close - it is currently aimed for March or April 2012.

Comments:

Post a Comment:
  • HTML Syntax: NOT allowed
About

C++ enthusiasts only, please! ;)

Search

Categories
Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today