I get it, but many of the guarantees the BEAM provides come from limitations imposed by BEAM languages.
BEAM provides effective preemption of processes by counting function calls made by the process; the is effectively preemptive, because BEAM languages require recursion to implement loops.
BEAM has a simple GC with one heap per process. This is made possible because BEAM languages have immutable variables which can only reference older variables; and data is copied to rather than shared with other processes. (Caveat: ets and shared heap refcounted binaries allow for sharing with some additional complexity in the GC)
One heap per process also enables process isolation and fast and simple destruction of processes.
It's hard to build a similarly constrainted environment in C++ and if you did, you would likely not be able to use a lot of existing code. Maybe you don't want GC anyway, and you could use OS process isolation, but I've run Erlang nodes with millions of processes, and I don't think that's feasible with OS processes.