All tutorials
C++
The C++ API wrapper provides a synchronous, type-safe way to use the what3words Public API from C++17 applications, without managing HTTPS requests or response parsing yourself.
This wrapper calls the hosted Public API. It is separate from the offline C++ Core SDK and does not require an Enterprise Suite installation.
A full example of how to integrate the what3words C++ wrapper is available in our
C++ Github repository
Use a supported C++17 compiler and CMake to add the wrapper to your application.
| C++17 | MSVC 2019+, GCC 9+, Clang 10+, or supported Apple Clang |
| CMake | CMake 3.20 or newer |
| Git | Required for FetchContent and source builds |
| Dependencies | libcurl and nlohmann/json |
CMake can fetch missing dependencies for FetchContent and standalone source builds. The repository also provides a vcpkg.json manifest. An installable CMake package requires an installed libcurl. The fully system-resolved install recipe below disables dependency fetching, so it also requires nlohmann/json as an installed CMake dependency.
CMake FetchContent
Add the wrapper directly to an application with CMake FetchContent:
include(FetchContent) FetchContent_Declare( what3words_api GIT_REPOSITORY https://github.com/what3words/w3w-cpp-wrapper GIT_TAG v1.0.0 ) FetchContent_MakeAvailable(what3words_api) target_compile_features(your-target PRIVATE cxx_std_17) target_link_libraries(your-target PRIVATE what3words::api)
Use an immutable released version so that later wrapper changes cannot break an existing application build. The wrapper also exports its C++17 requirement, but declaring the application target’s requirement makes the project contract explicit.
Build the wrapper source
Clone the released source before using the standalone build commands:
git clone https://github.com/what3words/w3w-cpp-wrapper what3words-api-cpp cd what3words-api-cpp
Static libraries are built by default. Add -DBUILD_SHARED_LIBS=ON for a shared library. On Windows, place the wrapper and libcurl DLLs beside the consuming executable or on PATH.
Windows with vcpkg
Configure with the vcpkg toolchain so that the manifest supplies libcurl and nlohmann/json:
cmake -S . -B build ` -A x64 ` -DCMAKE_TOOLCHAIN_FILE="$env:VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake" ` -DW3W_BUILD_TESTS=OFF ` -DW3W_BUILD_EXAMPLES=ON cmake --build build --config Release
Linux and macOS
Use GCC, Clang or Apple Clang with a single-configuration CMake build. On Linux, install the distribution’s TLS development package first if CMake will fetch libcurl.
cmake -S . -B build \ -DCMAKE_BUILD_TYPE=Release \ -DW3W_BUILD_TESTS=OFF \ -DW3W_BUILD_EXAMPLES=ON cmake --build build
Install and consume the CMake package
Only fetching libcurl disables installation; fetching nlohmann/json alone is compatible with the install rules. The fully system-resolved recipe below is for Linux and macOS. It disables dependency fetching, chooses an installation prefix, then installs the wrapper:
cmake -S . -B build-install \ -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_INSTALL_PREFIX=/your/prefix \ -DW3W_FETCH_DEPENDENCIES=OFF \ -DW3W_BUILD_TESTS=OFF \ -DW3W_BUILD_EXAMPLES=OFF cmake --build build-install cmake --install build-install
On Windows, use the vcpkg toolchain from the earlier build and pass the Release configuration to both build and install:
cmake -S . -B build-install ` -A x64 ` -DCMAKE_TOOLCHAIN_FILE="$env:VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake" ` -DCMAKE_INSTALL_PREFIX="$PWD/stage" ` -DW3W_FETCH_DEPENDENCIES=OFF ` -DW3W_BUILD_TESTS=OFF ` -DW3W_BUILD_EXAMPLES=OFF cmake --build build-install --config Release cmake --install build-install --config Release
The consuming build must also be able to resolve CURL. Add the installed wrapper to the application with:
find_package(what3words-api 1.0 CONFIG REQUIRED) target_compile_features(your-target PRIVATE cxx_std_17) target_link_libraries(your-target PRIVATE what3words::api)
-DCMAKE_PREFIX_PATH=/your/prefix on Linux/macOS or -DCMAKE_PREFIX_PATH="$PWD/stage" on Windows. Alternatively, set what3words-api_DIR to the directory containing what3words-api-config.cmake. If libcurl is fetched during a standalone build, install rules are disabled because the resulting dependency graph cannot be exported as a relocatable package. FetchContent and add_subdirectory consumption continue to work normally.Create an API key through the what3words developer portal. In the examples below, replace "your API key here" with your API key.
Keep API keys out of source control. The inline value keeps the examples concise. Do not commit or distribute source containing a real production key. The wrapper sends the key in the X-Api-Key header and prevents additional headers from replacing it.
The following complete program creates a client and converts a what3words address to latitude and longitude:
#include <chrono> #include <iomanip> #include <iostream> #include <variant> #include <what3words/api.hpp> int main() { try { const what3words::Client client("your API key here"); const auto result = client.convert_to_coordinates("filled.count.soap"); std::cout << std::fixed << std::setprecision(6) << result.coordinates.lat << ", " << result.coordinates.lng << '\n'; return 0; } catch (const what3words::ApiError& error) { std::cerr << error.code() << ": " << error.api_message() << '\n'; } catch (const what3words::Error& error) { std::cerr << error.what() << '\n'; } return 2; }
Expected output:
51.520847, -0.195521
The remaining C++ fragments assume the configured client and standard-library headers established by Quick start. <chrono> and <variant> are included in the complete setup because later timeout and GeoJSON fragments use them.
Configure timeouts and client identity
Defaults are 5 seconds for connection and 10 seconds for a request. Set non-default values before constructing the client.
what3words::ClientConfig config; config.api_key = "your API key here"; config.connect_timeout = std::chrono::seconds{3}; config.request_timeout = std::chrono::seconds{15}; config.user_agent = "your-application/1.0"; const what3words::Client client(config);
Thread safety. The default client can be called concurrently: configuration is immutable and each request uses its own libcurl easy handle.
Convert coordinates to a what3words address
Find the what3words address for 51.520847, -0.195521:
const auto address = client.convert_to_3wa( {51.520847, -0.195521}, what3words::ConvertTo3waOptions{}.language("en") ); std::cout << "///" << address.words << '\n';
These helpers can detect text that looks like a what3words address before making an API request:
const bool possible = what3words::is_possible_3wa("///filled.count.soap"); const auto matches = what3words::find_possible_3wa( "Meet at filled.count.soap" ); const bool looks_mistyped = what3words::did_you_mean("filled count soap"); // Makes an AutoSuggest API request to verify the address const bool valid = client.is_valid_3wa("filled.count.soap"); std::cout << std::boolalpha << "Possible format: " << possible << '\n' << "Matches found: " << matches.size() << '\n' << "Looks mistyped: " << looks_mistyped << '\n' << "Valid address: " << valid << '\n';
Format is not validity. is_possible_3wa runs locally and checks only the text format. Use is_valid_3wa to verify that an address exists.
See Detecting if text is in the format of a what3words address using RegEx for the C++ expressions.
The wrapper exposes specific error types for configuration, transport, API, HTTP and response parsing failures.
| Error | When it is used |
|---|---|
| InvalidArgumentError | Locally invalid coordinates, options or configuration |
| TransportError | DNS, connection, timeout or TLS failure |
| ApiError | A structured what3words API error with HTTP status, code and message |
| HttpError | A non-success HTTP response without a structured API error |
| ParseError | A successful response that does not match the expected contract |
try { const auto result = client.convert_to_coordinates("filled.count.soap"); std::cout << "///" << result.words << '\n'; } catch (const what3words::ApiError& error) { std::cerr << error.status_code() << " " << error.code() << ": " << error.api_message() << '\n'; } catch (const what3words::TransportError& error) { std::cerr << "Network error: " << error.what() << '\n'; } catch (const what3words::Error& error) { std::cerr << error.what() << '\n'; }
Endpoint availability and quotas depend on the API plan associated with the key.
ApiError.