It comes down to threads versus processes.
Operating systems were specifically designed so that each 'user' thought they had the whole computer to themselves - which is why you run apache as user wwwrun for instance.
Programmers, being programmers, started overloading that paradigm, first by each human user running multiple 'jobs'. Because operating systems were designed for multiple users, the upper scaling limit of that architecture reflected the upper scaling limit for logged in users - which is why apache, for instance, will start dying at 4,000 - 8,000 users.
Processes are a mature paradigm (my process can't crash yours). When we start seeing the introduction of threads though, things start getting very different. Here we have programmes that have external blocking activities (waiting on disk, waiting on io, waiting on memory) wanting to be able to wait on the one hand, and work on the other and threads allow you to do this and overcome two problems:
you can't get enough processes because the operating system can't handle it
each process is expensive because, by design, it gives the 'user' the full power of the operating system
The problem with threads is that they break the separation that processes were designed for. My thread can trash your thread - errors propagate.
Where Erlang is different is in a number of respects. Joe Armstrong's PhD Thesis is called Making Reliable Distributed Systems In The Presence Of Software Errors.
Reliability means processes are better than threads. The problem is that operating systems processes are too 'expensive' because they are designed for humans (you own the machine) and not concurrent units of programmes. In the Erlang VM, the VM has the full power of a multi-user system (it runs in an operating system process) and each Erlang process has a much smaller quantum of concurrent power - if it wants to use the 'big machine' it talks to the VM which does it for it. So Erlang processes are much cheaper than operating processes (and threads). You just spawn, spawn, spawn. Out of the box Erlang VM's start with 2**8 processes, but you can bump that up to millions (if you have enough RAM).
Also, as Joe put it in the first part of the first Section of his PhD Thesis, to have reliable software you need to start with two computers. With Erlang/OTP, at write time you don't know which computer your software will be running on. The Erlang/OTP cluster, at run time, will allocate your computational work. So an Erlang process is native distributed, as is spawn() (Erlang for fork()) and restart semantics.
Because Erlang has its own processes, it has its own scheduler and its own code loader/binary format (Erlang can be interpreted or it can compile to native binaries). This then gives a squad of additional benefits - before you write your Erlang/OTP application it can already hot swap its binaries out, etc, etc
So, sure you can write multi-threaded apps in C++ - but it is your responsibility to prevent error propagation and build system stability.
And sure, you can build reliable software in C - look at Erlang (the VM is written in C) the point is why would you want to? In the olden days, companies wrote their own 'operating systems', you could write your own operating system now, but why would you want to? There are millions of lines of robust tested code that 'does it', just like there is 1.5m lines of robust tested code in the Erlang/OTP system that 'does it'.
Using Erlang is about using the things that other people have written and only building the bits that make your company effective.