|
1 | 1 |
|
2 | 2 | # Common expressions
|
3 | 3 |
|
| 4 | +## Calling functions: `f(x)` syntax, and `x.f()` UFCS syntax |
| 5 | + |
| 6 | +A function call like `f(x)` is a normal function call that will call non-member functions only, as usual in C++. |
| 7 | + |
| 8 | +A function call like `x.f()` is a unified function call syntax (aka UFCS) call. It will call a member function if one is available, and otherwise will call `f(x)`. Having UFCS is important for generic code that may want to call a member or a non-member function, whichever is available. It's also important to enable fluid programming styles and natural IDE autocompletion support. |
| 9 | + |
| 10 | +An operator notation call like `#!cpp a + b` will call an overloaded operator function if one is available, as usual in C++. |
| 11 | + |
| 12 | +For example: |
| 13 | + |
| 14 | +``` cpp title="Function calls" hl_lines="3 7 11 16 19 20" |
| 15 | +// Generic function to log something |
| 16 | +// This calls operator<< using operator notation |
| 17 | +log: (x) = clog << x; |
| 18 | + |
| 19 | +f: ( v : std::vector<widget> ) = { |
| 20 | + // This calls log() with the result of std::vector::size() |
| 21 | + log( v.size() ); |
| 22 | + |
| 23 | + // This calls log() with the result of std::ssize(v), because |
| 24 | + // v doesn't have a .ssize member function |
| 25 | + log( v.ssize() ); |
| 26 | +} |
| 27 | + |
| 28 | +// Generic function to print "hello, ___!" for any printable type |
| 29 | +hello: (name) = { |
| 30 | + myfile := fopen("xyzzy.txt", "w"); |
| 31 | + // Direct calls to C nonmember functions, using UFCS and safe |
| 32 | + // string interpolation (instead of type-unsafe format strings) |
| 33 | + myfile.fprintf( "Hello, (name)$!\n" ); |
| 34 | + myfile.fclose(); |
| 35 | + // The C and C++ standard libraries are not only fully available, |
| 36 | + // but safer (and arguably nicer) when used from Cpp2 syntax code |
| 37 | +} |
| 38 | +``` |
| 39 | + |
| 40 | +To explicitly treat an object name passed as an argument as `move` or `out`, write that keyword before the variable name. |
| 41 | + |
| 42 | +- Explicit `move` is rarely needed. Every definite last use of a local variable will apply `move` by default. Writing `move` from an object before its definite last use means that later uses may see a moved-from state. |
| 43 | + |
| 44 | +- Explicit `out` is needed only when initializing a local variable separately from its declaration using a call to a function with an `out` parameter. For details, see [Guaranteed initialization](../cpp2/objects.md#Init). |
| 45 | + |
| 46 | +For example: |
| 47 | + |
| 48 | + |
| 49 | + |
4 | 50 | ## `_` — the "don't care" wildcard, including explicit discard
|
5 | 51 |
|
6 | 52 | `_` is pronounced **"don't care"** and allowed as a wildcard in most contexts. For example:
|
|
0 commit comments