All tutorials

C++

intermediate

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
github icon white C++ Github repository

1Requirements

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
CMakeCMake 3.20 or newer
GitRequired for FetchContent and source builds
Dependencieslibcurl 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.

2Installation

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)
Copied

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
Copied

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
Copied

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
Copied

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
Copied

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
Copied

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)
Copied
When using a custom installation prefix, configure the consuming application with -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.
3Setup an API key

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.

4Quick start

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;
}
Copied

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);
Copied

Thread safety. The default client can be called concurrently: configuration is immutable and each request uses its own libcurl easy handle.

5API operations

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';
Copied
6RegEx functions

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';
Copied

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.

7Error handling

The wrapper exposes specific error types for configuration, transport, API, HTTP and response parsing failures.

ErrorWhen it is used
InvalidArgumentErrorLocally invalid coordinates, options or configuration
TransportError DNS, connection, timeout or TLS failure
ApiErrorA structured what3words API error with HTTP status, code and message
HttpErrorA non-success HTTP response without a structured API error
ParseErrorA 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';
}
Copied

Endpoint availability and quotas depend on the API plan associated with the key.

HTTP 402 responses. An HTTP 402 response can indicate that a feature is unavailable on the current plan or that a plan quota has been exceeded. A structured response is surfaced as ApiError.
Server and ScriptingC++

Related tutorials