2025 Mar 28
For C++ programmers, to build familiarity with the commonalities and differences between the two languages.
Fields with a warning label (⚠️) were suggested by ChatGPT and I cannot vouch for them.
C++ | Rust | Description |
---|---|---|
cppreference.com | doc.rust-lang.org | Standard library documentation |
(No equivalent) | docs.rs | Central documentation for third-party packages |
⚠️ vcpkg or Conan | crates.io | Search for third-party packages |
Compiler Explorer | Compiler Explorer | Test and share code snippets online |
C++ | Rust | Description |
---|---|---|
CMake | Cargo | High-level build system |
cmake --build build && build/hello_world | cargo run | Build and run |
g++ | rustc | Low-level compiler. You never need to call rustc directly, use cargo instead. |
*.cpp | *.rs | Source code files |
*.h | (Not needed) | Rust does not use header files |
CMakeLists.txt | Cargo.toml | Project-level configuration file |
AStyle | cargo fmt | Enforces standard formatting and style |
clang-tidy | cargo clippy | Warns about issues that are not compile errors, but are not idiomatic code |
Doxygen | cargo doc | Generate HTML documentation from comments in the code. |
⚠️ mull | cargo-mutants | Mutation testing. Finds lines of code that aren't covered by automated tests. |
C++ | Rust | Description |
---|---|---|
std::chrono::duration | std::time::Duration | A time interval |
std::chrono::steady_clock::now() | std::time::Instant::now() | Returns the current monotonic time |
std::optional<T> | Option<T> | An optional value |
std::variant<T, E> | Result<T, E> | A type representing success or failure. Rust's Result is much easier to use. |
std::string | String | Text string. Note that in C++, strings are zero-terminated. In Rust they are not zero-terminated, but they are guaranteed to be valid UTF-8. |
std::string_view | &str | A reference to a slice of a string. &str is more common in Rust than string_view is in C++. |
std::vector<T> | Vec<T> | Growable array of items |
std::vector<uint8_t> | Vec<u8> | Growable array of bytes |
const vector<uint8_t> & | &[u8] | Reference to a slice of bytes |
vector::size() | Vec::len() | Number of elements in a collection |
vector::push_back() | Vec::push() | Append an element to a vector |
C++ | Rust | Description |
---|---|---|
using std::vector; | (Not needed) | Vec is already in Rust's standard prelude |
using std::map; | use std::collections::BTreeMap; | Imports the standard ordered generic map type |
if (x) { } else { } | if x { } else { } | If-statements don't need parens in Rust |
switch (x) | match x | Branches on a variable, like an if-else chain |
int greet_user(const string & name) {} | fn greet_user(name: &str) -> anyhow::Result<()> {} | A function that takes a string reference and may return an error |
cout << "Hello " << user << endl | println!("Hello {user}") | Writing to stdout and interpolating variables |
throw std::runtime_error("Oops") | anyhow::bail!("Oops") | Throwing an error |
cerr << "Error: " << error.what() << endl | eprintln!("Error: {}", error.to_string()) | Writing the message of an error to stderr |
const int x; | let x = 0; | Declaring a variable. Rust variables must be initialized, the types are inferred by default, and they are constant by default. |
uint64_t y; | let mut y = 0u64; | Declaring a mutable unsigned 64-bit number. |
for (int i = 0; i < 100; i++) {} | for i in 0..100 {} | Loop from 0 to 99 |
for (const auto x: my_vec) {} | for x in &my_vec | Loop over all elements in a collection |
return 0; | Ok(()) | Return from a function without errors. Rust does not need the explicit return keyword or semicolon on the last line of a function. Rust uses the Result<T, E> enum instead of C-style ints for error handling. |
struct MyStruct { uint32_t x = 0; }; | struct MyStruct { x: u32; } | Rust does not need semicolons after structs, and it does not need variables to have an initial value in the struct declaration, since variables are required to be initialized when used. |
class MyClass: SuperClass | (No equivalent) | Rust does not have inheritance for data structures. Traits are used instead. |
const auto x = sum(my_vec); | let x = sum(&my_vec); | In C++, passing a reference is implicit at the call site, but in Rust it requires an explicit ampersand. |
const auto deep_copy = my_vec; | let deep_copy = my_vec.clone(); | In C++, deep-copying is sometimes implicit. In Rust, it is always explicit. |
std::tuple<A, B, C> | (A, B, C) | In Rust, tuples are built into the language. |
C++ | Rust | Description |
---|---|---|
(No direct equivalent) | anyhow | Error handling |
nlohmann::json | serde_json | JSON serializer / parser |
libcurl | reqwest | HTTP(S) client |
Qt / libuv | Tokio | Asynchronous event loop framework |
⚠️ spdlog, glog, Boost.Log | tracing | Logging |
⚠️ pybind11 | PyO3 | Generate native modules for Python easily |
⚠️ Crow, Pistache, Boost.Beast | axum | Web application framework |
Licensed CC BY-SA 4.0, that means you must not train proprietary LLMs on this.