# Union splitting vs C++

**URL:** <https://discourse.julialang.org/t/union-splitting-vs-c/61772>\
**Category:** Performance\
**Created:** [May 25, 2021, 12:21pm UTC](https://discourse.julialang.org/t/union-splitting-vs-c/61772 "2021-05-25T12:21:49Z")\
**Posts on this page:** 1\
**Showing post:** 13

<div class="post-metadata">

**Author:** ![anon56330260](https://avatars.discourse-cdn.com/v4/letter/a/f07891/32.png) [@anon56330260](https://discourse.julialang.org/u/anon56330260)\
**Post date:** [May 25, 2021, 3:23pm UTC](https://discourse.julialang.org/t/union-splitting-vs-c/61772/13 "2021-05-25T15:23:03Z")

</div>

Vtable alone is not enough. You need to use function poiners and object pointers together to get around type inference. Virtual function is simply a function taking an object pointer as the first parameter (that is `self`). So we need to do something like this:

```julia
f1(self::Ptr{Void},args...) = ...
f2(self::Ptr{Void},args...) = ...
#then use FunctionWrapper to wrap f1 and f2
mutable struct S
    methodtable::MethodList{FunctionPointer}
    #add custom function table here, MethodList{FunctionPointer} is a pointer array
    #you can also store class property 
    #other field
end

```

This is basically how C++ people implement their vtables. `Ptr{Void}` is a must to eliminate different types. So you need to use mutable types to take the pointer, then cast it to `Ptr{Void}`. You can also use immutable types if they are wrapped in `Base.RefValue`(like shared\_ptr in C++). And you now don’t have arrays with abstract types, you have array with `Ptr{Void}`. To call a specific method, we need to calculate the corresponding offset in method table (in compile time), and invoke that function with the pointer.  
This approach actually works in current Julia(I have tried a small prototype in a raytracer project), but programmer needs to create and maintain method table manually. Also, since raw pointer is not tracked by GC, sometimes we need to ensure the lifetime of the object is long enough by using `GC.@preserve`.  
So the core problem here is that, to use vtable programmer needs to use pointer explicitly everywhere. In C++, `self` is an implicit parameter and handled by compiler. Programmer doesn’t need to write out its signature `Ptr{Void}`. Also, pointer casting is needed from Ptr{Void} to the concrete types when you use the pointer.This type of thing cannot be abstracted away by designing a vtable library carefully.

---

_[View the full topic](https://discourse.julialang.org/t/union-splitting-vs-c/61772)._
