It's awesome to see this getting so much interest! Thanks for the great post, Alex.
I've been seeing a lot of questions about C++ interop in response to this post, and I just wanted to use this as an opportunity to answer a couple common ones. That being said, feel free to post any questions here, and I'll do my best to answer them.
Is C++ interop supported/shipping?
No. C++ interop is not supported (yet). Some things are working (quite well actually), so feel free to try it out, if you're interested. But I want to be very clear: C++ interop is not a supported feature.
An experimental version of C++ interop has shipped with most of the recent Swift compilers, however, it is still very unstable, and you will likely see crashes and mis-compiles. In the past few weeks I've been making stability a priority, so future compilers will hopefully be more stable.
If you want to try it out, play around with it, test it, etc. you can use -Xfrontend -enable-cxx-interop. But remember, this is not a supported feature, and it is likely to cause crashes and mis compiles.
How does this fit with Objective-C/C interop?
C++ interop composes nicely with existing Objective-C and C interop. On macOS Objective-C interop is enabled by default (and required) so you're really going to already be using Objective-C++ interop (allowing use of both Objective-C and C++ APIs).
On other platforms, C++ interop is pure C++ interop; you can't use Objective-C APIs (at least by default).
Does this require any work from the user's side?
Not really. By default, you should be able to automatically consume all (or many) of your C++ APIs without any extra work. They will just be automatically imported like Objective-C APIs. That means you don't have to define any bridging functions or API mappings. The two exceptions to this are: 1) you will still have to create either a module map or a bridging header so the compiler knows what headers to import and 2) ideally you will annotate your APIs with _Nullable and _Nonnull attributes (but this is optional).
Does interop jump through wrapper functions?
No! One of the goals of interop is to provide a fast, native-feeling experience. So, unlike bridging interfaces in most other languages, Swift's C++ interop will import types natively and call functions directly. This means you're getting the absolute maximum performance possible (note: there are a few cases where the compiler has to create a thunk or something, but these are rare, and usually inlined away).
Not only is there little to no performance overhead, but in many cases, it's actually faster than going through a C bridging layer. Let's take a common example: bridging std::string. If a user relies on a C++ API that uses std::string, they have to copy the contents of that string into some heap memory and pass that heap memory to Swift through a C bridging layer. Because this is manually allocated heap memory, the Swift program has to remember to deallocate it. So, not only does this introduce an expensive copy, but also introduces unsafety and complexity. C++ interop allows users to get rid of this kind of bridging code. Instead, they can call their C++ API directly, so they don't need to copy their string onto the heap. When the object is done being used, the compiler will invoke string's destructor. Now, the program is safer, faster, and simpler!