documents member (#22460)

* documents member

* Apply suggestions from code review

Co-authored-by: Juan Carlos <juancarlospaco@gmail.com>

* Update doc/manual_experimental.md

* Update doc/manual_experimental.md

* Update doc/manual_experimental.md

* Update doc/manual_experimental.md

* Update doc/manual_experimental.md

* Update doc/manual_experimental.md

---------

Co-authored-by: Juan Carlos <juancarlospaco@gmail.com>
Co-authored-by: Andreas Rumpf <rumpf_a@web.de>
This commit is contained in:
Juan M Gómez
2023-08-12 09:37:52 +01:00
committed by GitHub
parent 23f3f9ae2c
commit f642c9dbf1

View File

@@ -2381,3 +2381,62 @@ proc makeCppClass(): NimClass {.constructor: "NimClass() : CppClass(0, 0)".} =
In the example above `CppClass` has a deleted default constructor. Notice how by using the constructor syntax, one can call the appropiate constructor.
Notice when calling a constructor in the section of a global variable initialization, it will be called before `NimMain` meaning Nim is not fully initialized.
Member pragma
=============
Similar to the `constructor` and `virtual` pragmas, the `member` pragma can be used to attach a `proc` or `func` to a type in C++.
It is more flexible than `virtual` in the sense that it accepts not only names but also operators or destructors.
For example:
```nim
proc print(s: cstring) {.importcpp: "printf(@)", header: "<stdio.h>".}
type
Doo {.exportc.} = object
test: int
proc memberProc(f: Doo) {.member.} =
echo $f.test
proc destructor(f: Doo) {.member: "~'1()", used.} =
print "destructing\n"
proc `==`(self, other: Doo): bool {.member: "operator==('2 const & #2) const -> '0".} =
self.test == other.test
let doo = Doo(test: 2)
doo.memberProc()
echo doo == Doo(test: 1)
```
Will print:
```
2
false
destructing
destructing
```
Notice how the C++ destructor is called automatically. Also notice the double implementation of `==` as an operator in Nim but also in C++. This is useful if you need the type to match some C++ `concept` or `trait` when interoping.
A side effect of being able to declare C++ operators, is that you can now also create a
C++ functor to have seamless interop with C++ lambdas (syntactic sugar for functors).
For example:
```nim
type
NimFunctor = object
discard
proc invoke(f: NimFunctor; n: int) {.member: "operator ()('2 #2)".} =
echo "FunctorSupport!"
{.experimental: "callOperator".}
proc `()`(f: NimFunctor; n:int) {.importcpp: "#(@)" .}
NimFunctor()(1)
```
Notice we use the overload of `()` to have the same semantics in Nim, but on the `importcpp` we import the functor as a function.
This allows to easy interop with functions that accepts for example a `const` operator in its signature.