diff --git a/README.md b/README.md
index 0546f13..1424692 100644
--- a/README.md
+++ b/README.md
@@ -7,6 +7,12 @@ Technical details for the current stage of the experiment can be found [on the I
Most of this code requires a recent nightly Rust compiler.
+## Experimental Outcomes
+
+Some outcomes of this experiment are summarised in the [C++ overloads in Rust](https://github.com/rustfoundation/overloading-macros/blob/main/cpp-overloads-in-rust.md) document & compatibility table.
+
+These outcomes are based on the current state of the experimental compiler feature and overloading macro: they are not Rust language design decisions.
+
## Macro Setup
Install a recent version of the nightly Rust compiler, and use it to build your project.
diff --git a/cpp-overload-test/examples/stdcpp-forward-list.rs b/cpp-overload-test/examples/stdcpp-forward-list.rs
index 101352d..d3e407d 100644
--- a/cpp-overload-test/examples/stdcpp-forward-list.rs
+++ b/cpp-overload-test/examples/stdcpp-forward-list.rs
@@ -1,4 +1,10 @@
-//! Test C++ overloads that can't be represented in Rust, and record the macro diagnostics.
+//! Test C++ [std::forward_list][forward_list] overloads that can't be represented in Rust, and record the macro diagnostics.
+//! Error output is in [stdcpp-forward-list.stderr].
+//! Working overloads are in [forward_list.rs].
+//!
+//! [forward_list]: https://en.cppreference.com/cpp/container/forward_list
+//! [stdcpp-forward-list.stderr]: https://github.com/rustfoundation/overloading-macros/blob/main/cpp-overload-test/examples/stdcpp-forward-list.stderr
+//! [forward_list.rs]: https://github.com/rustfoundation/overloading-macros/blob/main/cpp-overload-test/src/stdcpp/forward_list.rs
//!
//! The `cpp!` macro doesn't work here, because of technical limitations it can only run one build
//! per crate. (Examples and binaries are built separately from `lib.rs`.)
diff --git a/cpp-overload-test/src/stdcpp/forward_list.rs b/cpp-overload-test/src/stdcpp/forward_list.rs
index 90bec92..228f7cb 100644
--- a/cpp-overload-test/src/stdcpp/forward_list.rs
+++ b/cpp-overload-test/src/stdcpp/forward_list.rs
@@ -1,4 +1,9 @@
-//! Test that C++ overloads for `std::forward_list` can be successfully represented in Rust.
+//! Test that C++ overloads for [std::forward_list][forward_list] can be successfully represented in Rust.
+//! Failing overloads are in [stdcpp-forward-list.rs], and error output is in [stdcpp-forward-list.stderr].
+//!
+//! [forward_list]: https://en.cppreference.com/cpp/container/forward_list
+//! [stdcpp-forward-list.rs]: https://github.com/rustfoundation/overloading-macros/blob/main/cpp-overload-test/examples/stdcpp-forward-list.rs
+//! [stdcpp-forward-list.stderr]: https://github.com/rustfoundation/overloading-macros/blob/main/cpp-overload-test/examples/stdcpp-forward-list.stderr
#![allow(unused_braces)]
diff --git a/cpp-overloads-in-rust.md b/cpp-overloads-in-rust.md
new file mode 100644
index 0000000..db97b9e
--- /dev/null
+++ b/cpp-overloads-in-rust.md
@@ -0,0 +1,103 @@
+
+# C++ Overloads in Rust: Experimental Outcomes
+
+***This document is an initial, partially reviewed draft***
+
+This table shows how well C++ standard library overloads can be represented in Rust.
+
+These outcomes are based on the current state of the experimental `splat` compiler feature and
+overloading macro: they are not Rust language design decisions.
+
+See the Limitations section below the table for more details.
+
+*Key:*
+⛔ Conflicting Overloads
+🦀 Rust Compiler Limitations
+⚙️ Overload Macro Limitations
+🌗 Partial Support or Poor Ergonomics
+✅ Works in Rust
+? Needs Analysis
+*blank* No C++ Overloads
+
+| C++ Standard Library Class | Constructors | Accessors | Modifiers | Transforms |
+| :------------------------- | :----------- | :-------- | :-------- | :--------- |
+| *Free Functions* | Constructors | Accessors | Modifiers | Transforms |
+| TODO | | ? | ? | ? |
+| *Non-Template Classes* | Constructors | Accessors | Modifiers | Transforms |
+| TODO | ? | ? | ? | ? |
+| *Template Classes* | Constructors | Accessors | Modifiers | Transforms |
+| [forward_list] | ✅ | 🌗⚙️ | ? | ?[^1] |
+| TODO | ? | ? | ? | ? |
+
+Constructors: Create an instance of the class, called as `Class::Class(...)`
+Accessors: Get information about the class, called as `instance->get(...)`
+Modifiers: Add or change the items in a list class, called as `instance->put(...)`
+Transforms: Rearrange the items in a list class, called as `instance->sort(...)`
+
+[forward_list]: https://github.com/rustfoundation/overloading-macros/blob/main/cpp-overload-test/src/stdcpp/forward_list.rs
+
+[^1]: TODO: are [C++ predicate functions](https://en.cppreference.com/cpp/container/forward_list/unique) with const refs ABI-compatible with Rust?
+
+## Limitations
+
+This section summarises common issues discovered during the analysis, and documents less
+interesting overloads that were skipped.
+
+### Typical Overload Conflicts
+
+Overload macro missing functionality:
+
+- methods that only differ by `self` type, for example `get(&self) -> &T` and
+ `get(&mut self) -> &mut T`
+ - this can be worked around using associated functions, but the ergonomics suffer
+- Generic types:
+ - this makes representing C++ templated types with generic Rust types impossible
+ - doesn't support `impl Iterator` or `where I: Iterator` as arguments, but supports
+ `&dyn Iterator` (which is less ergonomic)
+- Lifetimes:
+ - generic lifetimes aren't supported
+ - when the input method has elided lifetimes, the generated code doesn't add lifetimes where
+ needed
+
+### Ergonomics
+
+Some overloads are confusing or hard to use, so we might not want to represent them in Rust:
+
+- `get(&self) -> &T` and `get(&mut self) -> &mut T` is a subtle difference, typical Rust APIs use
+ `get` and `get_mut` instead
+- in generic list overloads, `new(count: usize)` and `new(item: T)` are easily confused if `T` is
+ an integer (and they conflict if `T` is `usize`, which means it can't be fully generic)
+ - this can be resolved by skipping overloads for initializer lists
+- `&dyn Iterator` overloads require a type cast
+ - this could be resolved with improvements to the macro, or with an iterator adapter type
+
+Type inference doesn't work on some overloads: this is likely a macro or compiler experiment limitation.
+
+Some C++ overloads [use a tag argument][cpp-tag-arg] for [overload disambiguation][cpp-tag-type],
+a strategy which could be adopted in Rust APIs. But in some cases, the Rust overload
+[might not need disambiguation][rust-no-disambig].
+
+[cpp-tag-arg]: https://en.cppreference.com/cpp/container/forward_list/forward_list
+[cpp-tag-type]: https://en.cppreference.com/cpp/ranges/from_range
+[rust-no-disambig]: https://github.com/rustfoundation/overloading-macros/blob/52c3f3aa5e4e6f11d71d2d832fce733f00d0b087/cpp-overload-test/src/stdcpp/forward_list.rs#L89
+
+### Scope
+
+Some overloads have been ignored or minimised in this analysis.
+
+These overloads are less interesting:
+
+- overloaded operators: already available in stable Rust
+- overloads with an allocator argument, or that only differ by noexcept: not an interesting
+ difference
+- overloads that only differ by `const`/non-`const`, `&`/`&&` (lvalue/rvalue) in C++, or
+ `&`/`&mut` in Rust
+
+These overloads have no equivalent in Rust:
+
+- assignment functions, assignment operators, and `swap`: there is no "type move method" in Rust
+ (it uses `memcpy` for assignment/swaps)
+- legacy iterator pointer-like methods for various positions
+ (`before_begin`/`begin`/`end`/`after_end`)
+- initializer list methods: these are also a common source of overload conflicts for C++ templated
+ lists