[** ‼️ The official C++ interoperability documentation and status page is live at Swift.org and provides an up-to-date guide for mixing Swift and C++ ‼️ **](https://www.swift.org/documentation/cxx-interop/status) # C++ Interoperability Status Swift has some experimental ability to interoperate with C++. This document provides an overview of the status of the Swift and C++ interoperability support. ## C++ to Swift Interoperability Status Swift has the experimental ability to import a large subset of C++. This section of the document describes which C++ language and standard library features can be imported and used from Swift in an experimental manner. ### Example The following example demonstrates several interop features. It compiles and runs on main. ```C++ // cxx-types.h (mapped to CxxTypes module in module.modulemap) #include #include using V = std::vector; ``` ```Swift // main.swift import CxxTypes import CxxStdlib // We can extend C++ types in Swift. extension V : RandomAccessCollection { public var startIndex: Int { 0 } public var endIndex: Int { size() } } // Create a vector with some data. var numbers = V(4) std.fill(numbers.beginMutating(), numbers.endMutating(), 41) // Transform it using C++. std.transform(numbers.beginMutating(), numbers.endMutating(), numbers.beginMutating()) { (element: Int) in return element + 1 } // Loop over it in Swift. for (index, element) in numbers.enumerated() { print("v[\(index)] = \(element)") } // We can also use anything in RandomAccessCollection, such as map and zip. let strings = numbers.map { "\($0)" } for (s, n) in zip(strings, numbers) { print("\(s) = \(n)") } ``` ### Importing C++ There are currently two experimental ways to import C++ into Swift: - **Clang modules**: can be imported into Swift. This requires a module map. - **Bridging header**: can be imported into Swift. Headers included in the bridging header will be imported. Please note that support for importing C++ 20 modules isn’t implemented. Both CMake and the Swift package manager can be configured to invoke Swift with the correct arguments to import C++ headers. **Note**: C++ code is imported using the Objective-C++ language mode on Apple platforms. ### Experimental C++ Language Support This status table describes which of the following C++ language features can be used in Swift: | **C++ Language Feature** | **Implemented Experimental Support For Using It In Swift** | |---------------------------------------------|---------------------------------------------------------------| | Top-level functions | Yes | | Enumerations | Yes. That includes `enum class` | | Struct / Class types | Yes - as value types, except for types without a copy constructor. Partial experimental support for importing a C++ struct/class as a reference type | | Typedefs / Type aliases | Yes | | Global Variables | Yes | | Namespaces | Yes | | Inline Namespaces | Yes, with some known issues ([#58217](https://github.com/swiftlang/swift/issues/58217)) | | Exceptions | No. Uncaught exceptions that propagate into Swift frames are UB. | | Fields | Yes | | Member functions | Yes. Some value category overloads aren't imported | | Virtual Member Functions | No | | Operators | Yes, with some known issues | | Subscript Operators | Yes | | Constructors | Yes. That includes implicit constructors | | Destructor | Yes. C++ destructors are invoked automatically when the value is no longer used in Swift | | Copy constructor / copy assignment operator | Yes. Swift invokes the underlying copy constructor when copying a C++ value | | Move constructor / move assignment operator | No | | Base class member functions / operators | Yes, with some known issues | | Function templates | Yes | | Class templates | Yes | | Dependent types | Partially: imported as Any | | Availability Attributes | Yes | The following C++ code patterns or language features have specific mappings to Swift language features when imported in Swift: | **C++ Language Feature** | **Imported Into Swift** | |------------------------------------------------------|------------------------------------------------------------------------------------------| | `get`/`set` member functions | Imported as computed property (starting from Swift-5.7) | | `const`/non-`const` member function overload set | Both overloads are imported as a method, with non-`const` method being renamed to `mutating…` (starting from Swift-5.7). The renaming logic will change in a future version of Swift, and non-`const` methods won't be renamed | Unless stated otherwise (i.e., imported reference types) all Swift features work with imported types. For example: use in generic contexts, protocol conformance, extensions, etc. ### C++ Standard Library Support Parts of libc++ can be imported and used from Swift. C++ standard library types are bridged directly to Swift, and there is not automatic bridging to native Swift types. This means that if an imported C++ API returns `std::string`, you will get a `std::string` value in Swift as well, and not Swift's `String`. This status table describes which of the following C++ standard library features have some experimental support for using them in Swift. Please note that this is not a comprehensive list and other libc++ APIs that use the above supported C++ language features could be imported into Swift. | **C++ Standard Library Feature** | **Can Be Used From Swift** | |------------------------------------|----------------------------------------------| | `std::string` | Yes | | `std::vector` | Yes | ## Known Issues ### Inline Namespaces - [#58217](https://github.com/swiftlang/swift/issues/58217): Swift's typechecker currently doesn't allow calling a function from an inline namespace when it's referenced through the parent namespace. Example of a test that fails: https://github.com/swiftlang/swift/blob/main/test/Interop/Cxx/namespace/inline-namespace-function-call-broken.swift ## Swift to C++ Interoperability Status This section of the document describes which Swift language and standard library features can be imported and used from C++. ### Importing Swift Swift has some experimental support for generating a header that can be imported by C++. ### Swift Language Support This status table describes which of the following Swift language features have some experimental support for using them in C++. **Functions** Swift functions can be called from C++, with some restrictions. See this table for details: | **Swift Language Feature** | **Implemented Experimental Support For Using It In C++** | |--------------------------------|----------------------------------------------------------| | Top-level `@_cdecl` functions | Yes | | Top-level Swift functions | Yes | | Swift Methods | Yes (see the **Methods** section below for more details) | | Primitive parameter or result types | Yes | | Swift `struct`/`enum`/`class` parameter or result types | Yes | | `inout` parameters | Yes | | C++ `struct`/`class` parameter or result types | Yes | | Objective-C `@interface` parameter or result types | Yes | | Swift closure parameter or result types | No | | Swift protocol type parameter or result types | No | | SIMD type parameter or result types | No | | Variadic parameters | No | | Multiple return values | No | **Structs** | **Swift Language Feature** | **Implemented Experimental Support For Using It In C++** | |--------------------------------|----------------------------------------------------------| | Fixed layout structs | Yes | | Resilient / opaque structs | Yes | | Copy and destroy semantics | Yes | | Initializers | Yes (except for throwing initializers) | **Enums** | **Swift Language Feature** | **Implemented Experimental Support For Using It In C++** | |------------------------------|----------------------------------------------------------| | Fixed layout enums | Yes | | Resilient / opaque enums | Yes | | Copy and destroy semantics | Yes | | Creation | Yes | | Enums with associated values | Partially: only support structs and enums | | Enums with raw values | Yes | | Indirect enums | No | **Class types** | **Swift Language Feature** | **Implemented Experimental Support For Using It In C++** | |--------------------------------|----------------------------------------------------------| | Class reference values | Yes | | ARC semantics | Yes (C++ copy constructor,assignment operator, destructor perform ARC operations) | | Initializers | Yes (except for throwing initializers) | **Methods** | **Swift Language Feature** | **Implemented Experimental Support For Using It In C++** | |--------------------------------|----------------------------------------------------------| | Instance methods | Yes on structs and enums. Instance methods on class types are partially supported (virtual calls won't be virtual due to a bug right now) | | Static methods | No | **Properties** | **Swift Language Feature** | **Implemented Experimental Support For Using It In C++** | |--------------------------------|----------------------------------------------------------| | Getter accessors | Yes, via `get`. Boolean properties that start with `is` or `has` are remapped directly to a getter method using their original name | | Setter accessors | Yes, via `set` | | Mutation accessors | No | | Static property accessors | Yes | **Generics** | **Swift Language Feature** | **Implemented Experimental Support For Using It In C++** | |------------------------------|----------------------------------------------------------| | Generic functions | Partially, only without generic constraints | | Generic methods | Partially, only without generic constraints | | Generic `struct` types | Partially, only without generic constraints and less than 4 generic parameters | | Generic `enum` types | Partially, only without generic constraints and less than 4 generic parameters | | Generic `class` types | No | ### Swift standard library This status table describes which of the following Swift standard library APIs have some experimental support for using them in C++. | **Swift Library Type** | **Can be used from C++** | |--------------------------------|----------------------------------------------------------| | `String` | Can be used as a type in C++. APIs in extensions are not exposed to C++. Conversion between `std.string` is not yet supported | | `Array` | Can be used as a type in C++. Ranged for loops are supported. Limited set of APIs in some extensions are exposed to C++. | | `Optional` | Can be used as a type in C++. Can be constructed. `get` extracts the optional value and it's also implicitly castable to `bool`. |