Metadata
Title
Postfix Call Examples
Category
general
UUID
2478950f42434ae0a43f3db6179273a2
Source URL
https://cforall.uwaterloo.ca/features/postfixcall.shtml
Parent URL
https://cforall.uwaterloo.ca/features/
Crawl Time
2026-03-18T05:16:00+00:00
Rendered Raw Markdown

Postfix Call Examples

Source: https://cforall.uwaterloo.ca/features/postfixcall.shtml Parent: https://cforall.uwaterloo.ca/features/


Weight

Comparison of weight units.

C∀ C++
struct Weight { double stones; }; Weight ?+?( Weight l, Weight r ) { return l.stones + r.stones; } Weight ?`st( double w ) { return w; } double ?`st( Weight w ) { return w.stones; } Weight ?`lb( double w ) { return w / 14.0; } double ?`lb( Weight w ) { return w.stones * 14.0; } Weight ?`kg( double w ) { return w / 6.35; } double ?`kg( Weight w ) { return w.stones * 6.35; } int main() { Weight w, heavy = { 20 }; // stones w = 155`lb; w = 0b_1111`st; w = 0_233`lb; w = 0x_9b_u`kg; w = 5.5`st + 8`kg + 25.01`lb + heavy; } struct Weight { double stones; Weight() {} Weight( double w ) { stones = w; } }; Weight operator+( Weight l, Weight r ) { return l.stones + r.stones; } Weight operator""_st( long double w ) { return w; } Weight operator""_lb( long double w ) { return w / 14.0; } Weight operator""_kg( long double w ) { return w / 6.35; } Weight operator""_st( unsigned long long int w ) { return w; } Weight operator""_lb( unsigned long long int w ) { return w / 14.0; } Weight operator""_kg( unsigned long long int w ) { return w / 6.35; } int main() { Weight w, heavy = { 20 }; // stones w = 155_lb; w = 0b1111_lb; w = 0'233_lb; // quote separator w = 0x9b_kg; w = 5.5d_st + 8_kg + 25.01_lb + heavy; }

A common example for postfix functions is converting basic literals into user literals. The C∀ example (left) stores a mass in units of stones (1 stone = 14 lb or 6.35 kg) and provides an addition operator ?+? (imagine a full set of arithmetic operators). The arithmetic operators manipulate stones and the postfix operations convert to/from different units. The three postfixing function names st, lb, and kg, represent units stones, pounds, and kilograms, respectively. Each name has two forms that bidirectional convert: a value of a specified unit to stones, e.g., w = 14lb ⇒ w == 1 stone or a Weight from stones back to specific units, e.g., wlb (1 stone) to 14.

The C++ example (right) provides a restricted capability via user literals. The operator"" only takes a constant argument (i.e., no variable as an argument), and the constant type must be the highest-level constant-type, e.g., long double for all floating-point constants. As well, there is no constant conversion, i.e., int to double constants, so integral constants are handled by a separate set of routines, with maximal integral type unsigned long long int. Finally, there is no mechanism to use this syntax for a bidirectional conversion because operator"" only accepts a constant argument.


Time

Comparison of time units.

C∀ C++
#include <fstream.hfa> #include <time.hfa> Duration s = 1`h + 2 * 10`m + 70`s / 10; sout | "1 hour + 2*10 min + 70/10 sec = " | s | "seconds"; sout | "Dividing that by 2 minutes gives" | s / 2`m; sout | "Dividing that by 2 gives" | s / 2 | "seconds\n"; sout | s | "seconds is" | s`h | "hours," | (s % 1`h)`m | "minutes," | (s % 1`m)`s | "seconds"; #include <iostream> #include <chrono> using namespace std; using namespace std::chrono; seconds s = hours(1) + 2 * minutes(10) + seconds(70) / 10; cout << "1 hour + 2*10 min + 70/10 sec = " << s.count() << " seconds\n"; cout << "Dividing that by 2 minutes gives " << s / minutes(2) << '\n'; cout << "Dividing that by 2 gives " << (s / 2).count() << " seconds\n"; cout << s.count() << " seconds is " << duration_cast<hours>( s ).count() << " hours, " << duration_cast<minutes>( s % hours(1) ).count() << " minutes, " << duration_cast<seconds>( s % minutes(1) ).count() << " seconds\n";