> ## Documentation Index
> Fetch the complete documentation index at: https://docs.kameleoon.com/llms.txt
> Use this file to discover all available pages before exploring further.

# C++ SDK

> Kameleoon C++ SDK を統合して、C++ サービスおよびウェブバックエンドで実験を実行し、機能フラグを有効化します。

SDK をアプリケーションに統合するのは簡単で、フットプリント(メモリおよびネットワーク使用量)も小さく抑えられています。

**はじめに**: 入門ガイドについては、[開発者ガイド](#開発者ガイド)を参照してください。

**最新バージョン**: `0.8.5`。リリースノートについては [C++ SDK 変更履歴](https://github.com/Kameleoon-new/client-cpp/blob/main/CHANGELOG.md) を、すべての SDK については [SDK 変更履歴インデックス](/ja/developer-docs/sdks/versions) を参照してください。

**SDK メソッド**: C++ SDK の完全なリファレンスドキュメントについては、[リファレンス](#リファレンス)セクションを参照してください。

## 開発者ガイド

このガイドは、C++ SDK を迅速に統合し、C++ アプリケーションでフィーチャーフラグの評価を開始できるように設計されています。

### はじめに

#### C++ クライアントのインストール

C++ SDK は、Kameleoon SDK Core の上に構築された C++17 ライブラリです。SDK Core は、SDK の動作を実装する Rust 製のネイティブ共有ライブラリ(`libkameleoon_ffi`)です。アプリケーションは C++ ライブラリを静的にリンクし、コアライブラリを実行時にロードします。

<Warning>
  Kameleoon SDK Core は、ターゲットのプラットフォームおよびアーキテクチャに合わせてソースからコンパイルされます。**Rust** と **Cargo** がインストールされ、システムの `PATH` で利用可能であることを確認し、コアライブラリの C ヘッダーを生成する `cbindgen` をインストールしてください:

  ```bash theme={null}
  cargo install cbindgen --locked
  ```

  Rust と Cargo のインストール: [https://rust-lang.org/tools/install](https://rust-lang.org/tools/install)

  将来のリリースでは、インストールを簡素化するために、一般的なプラットフォーム向けのビルド済みコアライブラリが提供される予定です。ソースからビルドしたいユーザー向けに、ローカルコンパイルは引き続き利用可能です。
</Warning>

要件:

* C++17 コンパイラ(GCC、Clang、または MSVC)と CMake 3.16 以降。
* SDK Core ライブラリ(Linux では `libkameleoon_ffi.so`、macOS では `libkameleoon_ffi.dylib`、Windows ではインポートライブラリ `kameleoon_ffi.dll.lib` を伴う `kameleoon_ffi.dll`)をビルドするための Rust 1.91 以降、Cargo、および `cbindgen`。

[C++ SDK リポジトリ](https://github.com/Kameleoon-new/client-cpp) をクローンしてコアライブラリをビルドし、その後それに対して C++ ライブラリをビルドします:

```bash theme={null}
git clone https://github.com/Kameleoon-new/client-cpp.git
cd client-cpp

# Builds the SDK Core shared library into target/release
cargo build --locked -p kameleoon-ffi --release

# Builds the C++ library; cbindgen generates the core header during this step
cmake -S cpp/client -B cpp/client/build -DKAMELEOON_CPP_BUILD_TESTS=OFF -DKAMELEOON_CPP_BUILD_EXAMPLES=OFF
cmake --build cpp/client/build
```

SDK を独自の CMake プロジェクトに統合するには、`add_subdirectory()` で `cpp/client` ディレクトリを追加し、`Kameleoon::CppClient` ターゲットをリンクします。`KAMELEOON_FFI_LIBRARY` をビルドしたコアライブラリに向けてください。C ヘッダーは `cbindgen` で生成されますが、既存のヘッダーを `KAMELEOON_FFI_HEADER` で渡すこともできます:

```cmake title="CMakeLists.txt" theme={null}
set(KAMELEOON_FFI_LIBRARY "${CMAKE_SOURCE_DIR}/third_party/client-cpp/target/release/libkameleoon_ffi.so" CACHE FILEPATH "")
set(KAMELEOON_CPP_BUILD_TESTS OFF CACHE BOOL "")
set(KAMELEOON_CPP_BUILD_EXAMPLES OFF CACHE BOOL "")

add_subdirectory(third_party/client-cpp/cpp/client)

target_link_libraries(my_app PRIVATE Kameleoon::CppClient)
```

<Note>
  * `libkameleoon_ffi` は実行時にロードされます。標準のライブラリ配置場所にインストールするか、実行ファイルの隣に配置してください。Linux および macOS では、実行ファイルの隣に配置する場合、`$ORIGIN` または `@loader_path` の RPATH が必要です(たとえば、`set_target_properties(my_app PROPERTIES INSTALL_RPATH "$ORIGIN")`)。Windows では、`kameleoon_ffi.dll` をバイナリの隣にコピーします。
  * クライアントを作成すると、SDK はロードされた `libkameleoon_ffi` がビルド時のバージョンと一致するかどうかを確認し、一致しない場合は `ErrorCode::Internal` を伴う `KameleoonException` をスローします。C++ ライブラリとコアライブラリは常に一緒にアップグレードしてください。
  * すべての公開 SDK 型は `kameleoon` 名前空間にあります。公開 API 全体を取得するには `kameleoon/kameleoon.hpp` をインクルードしてください。
</Note>

#### 追加の構成

認証情報を提供し、SDK の動作をカスタマイズするために、JSON 構成ファイル(たとえば、`client-cpp.json`)を作成します。[サンプル構成ファイル](/assets/developer-docs/sdks/web-sdks/client-configs/client-config.json) をダウンロードすることもできます。

C++ SDK は、パスを `KameleoonClientFactory::create()` に渡す JSON ファイル、またはコード内で直接 `KameleoonClientConfig` 構造体に値を設定することで構成できます。

次の表は、設定可能なプロパティを示しています:

| キー (コード / 構成ファイル) | 説明 | デフォルト値 |
| - | - | - |
| `client_id` / `clientId` <Badge color="red" size="sm">必須</Badge> | Kameleoon サービスへの認証に必要です。`client_id` を確認するには、[API 認証情報](/ja/user-manual/account-and-team-management/users-and-teams/api-credentials) のドキュメントを参照してください。 | |
| `client_secret` / `clientSecret` <Badge color="red" size="sm">必須</Badge> | Kameleoon サービスへの認証に必要です。`client_secret` を確認するには、[API 認証情報](/ja/user-manual/account-and-team-management/users-and-teams/api-credentials) のドキュメントを参照してください。 | |
| `session_duration_minutes` / `sessionDurationMinutes` <Badge color="green" size="sm">任意</Badge> | SDK が訪問者とその関連データをメモリに保持する時間間隔(分)。 | `30` 分 |
| `refresh_interval_minutes` / `refreshIntervalMinutes` <Badge color="green" size="sm">任意</Badge> | アクティブな実験とフィーチャーフラグの構成を更新するために使用される間隔(分)。 | `60` 分 |
| `default_timeout_millis` / `defaultTimeoutMillis` <Badge color="green" size="sm">任意</Badge> | SDK のネットワークリクエストのデフォルトタイムアウト(ミリ秒)。 | `10000` ミリ秒 |
| `tracking_interval_millis` / `trackingIntervalMillis` <Badge color="green" size="sm">任意</Badge> | トラッキングリクエストをバッチ処理するために使用される間隔(ミリ秒)。値は `[1000, 5000]` の範囲にクランプされます。 | `1000` ミリ秒 |
| `environment` / `environment` <Badge color="green" size="sm">任意</Badge> | フィーチャーフラグ構成を使用する環境。値は `production`、`staging`、または `development` にできます。 | `std::nullopt`(`production` として扱われます) |
| `top_level_domain` / `topLevelDomain` <Badge color="green" size="sm">任意</Badge> | ウェブサイトの現在のトップレベルドメイン。プロトコルやサブドメインなしの `example.com` 形式を使用してください。 | `std::nullopt` |
| `proxy_host` / `proxyHost` <Badge color="green" size="sm">任意</Badge> | SDK の送信呼び出し用のプロキシホスト。サポートされる形式: `https://my.prox`、`https://my.prox:4545`、`socks5://192.168.1.1:9000`。 | `std::nullopt` |
| `network_domain` / `networkDomain` <Badge color="green" size="sm">任意</Badge> | SDK が送信リクエストに使用するカスタムドメイン。多くの場合プロキシ用です。有効なドメイン(例: example.com または sub.example.com)である必要があります。無効な形式の場合、Kameleoon のデフォルト値が使用されます。 | `std::nullopt` |

#### Kameleoon クライアントの初期化

SDK をインストールし、認証情報を構成したら、`KameleoonClientFactory` を使用して `KameleoonClient` を作成します。

<Tabs>
  <Tab title="構成ファイル">
    ```cpp theme={null}
    #include "kameleoon/kameleoon.hpp"

    using namespace kameleoon;

    KameleoonClient create_client()
    {
        const std::string site_code = "a8st4f59bj";

        KameleoonClient client = KameleoonClientFactory::create(site_code, "/etc/kameleoon/client-cpp.json");
        client.initialize();

        return client;
    }
    ```
  </Tab>

  <Tab title="コード">
    ```cpp theme={null}
    #include "kameleoon/kameleoon.hpp"

    using namespace kameleoon;

    KameleoonClient create_client()
    {
        const std::string site_code = "a8st4f59bj";

        KameleoonClientConfig config{
            .client_id = "<client-id>",                  // mandatory
            .client_secret = "<client-secret>",          // mandatory
            .refresh_interval_minutes = 60,              // optional (60 minutes by default)
            .session_duration_minutes = 30,              // optional (30 minutes by default)
            .default_timeout_millis = 10'000,            // optional (10000 ms by default)
            .tracking_interval_millis = 1'000,           // optional (1000 ms by default)
            .proxy_host = "http://192.168.0.25:8080",    // optional
            .environment = "development",                // optional
            .top_level_domain = ".example.com",          // mandatory if you use hybrid mode (engine or web experiments)
            .network_domain = "example.com",             // optional
        };

        KameleoonClient client = KameleoonClientFactory::create(site_code, config);
        client.initialize();

        return client;
    }
    ```
  </Tab>
</Tabs>

<Note>
  このページの例では、SDK の構成、オプション、およびデータ構造体に値を設定するために、C++20 の [指示付き初期化子](https://en.cppreference.com/w/cpp/language/aggregate_initialization#Designated_initializers)(`GetVariationOptions{.track = false}`)を使用しています。C++17 コンパイラの場合は、構造体を宣言し、フィールドを 1 つずつ設定してください。
</Note>

`KameleoonClient` は、フィーチャーフラグの評価、訪問者データの追加、トラッキングリクエストの送信に使用される主要なオブジェクトです。

<Warning>
  * `KameleoonClient` はアプリケーションと Kameleoon プラットフォームの間のブリッジとして機能するため、シングルトンオブジェクトとして使用することをお勧めします。実験を効率的に実行するために必要なすべてのメソッドとプロパティを公開しています。`KameleoonClient` はムーブ専用です。1 か所に保持し、参照で渡してください。
  * C++ SDK は非同期で初期化されます。本番コードでフィーチャー評価に依存する前に、[`initialize()`](#initialize) を呼び出す必要があります。
  * SDK のすべての失敗は [`KameleoonException`](#エラー処理) として報告されます。SDK 呼び出しは `try`/`catch` ブロックでラップしてください。
</Warning>

#### フィーチャーフラグの有効化

##### ユーザーへの一意の ID の割り当て

ユーザーに一意の ID を割り当てるには、[`get_visitor_code()`](#get_visitor_code) メソッドを使用できます。**訪問者コード**が存在しない場合(リクエストヘッダーのクッキーから)、メソッドはランダムな一意の ID を生成するか、生成しておいた `default_visitor_code` を使用します。ID はその後、レスポンスヘッダーのクッキーに設定されます。

Kameleoon を [ハイブリッドモード](/ja/developer-docs/feature-experimentation/get-started/hybrid-experimentation) で使用している場合、`get_visitor_code()` メソッドを呼び出すと、一意の ID(**訪問者コード**)がアプリケーションファイル `engine.js`(以前は `kameleoon.js` と命名)と SDK 間で共有されます。

##### フラグ構成の取得

コードにフィーチャーフラグを実装するには、まず Kameleoon アカウントでフィーチャーフラグを作成する必要があります。

特定のユーザーに対するフィーチャーフラグのステータスまたはバリエーションを判断するには、[`get_variation()`](#get_variation) または [`is_feature_active()`](#is_feature_active) メソッドを使用して、`feature_key` に基づいて構成を取得する必要があります。

`get_variation()` メソッドは、ON/OFF 状態の単純なフィーチャーフラグと、複数のバリエーションを持つより複雑なフラグの両方を処理します。このメソッドは、フィーチャールールをチェックし、バリエーションを割り当て、`feature_key` と `visitor_code` に基づいて返すことにより、ユーザーに適したバリエーションを取得します。

`is_feature_active()` メソッドは、複数のバリエーションやターゲティングオプションを持つより複雑なフィーチャーフラグとは対照的に、ON または OFF 状態のみを持つ単純なフィーチャーフラグの構成を取得したい場合に使用できます。

フィーチャーフラグに関連付けられた変数(各バリエーションに関連付けられた特定の動作など)がある場合、`get_variation()` を使用すると、割り当てられたバリエーションとその関連実験の詳細を提供する [`Variation`](#variation) オブジェクトにアクセスすることもできます。このメソッドは、フィーチャーフラグがユーザーをターゲットにしているかどうかを確認し、訪問者の割り当てられたバリエーションを見つけ、それをストレージに保存します。`track=true` の場合、SDK は次のトラッキングリクエストで指定された実験への露出イベントを送信します。これは、SDK の [`tracking_interval_millis`](#追加の構成) に基づいて自動的にトリガーされます。デフォルトでは、この間隔は 1000 ミリ秒(1 秒)に設定されています。

`get_variation()` メソッドを使用すると、SDK が訪問者をトラッキングするかどうかを制御できます。`track=false` の場合、SDK によって露出イベントは送信されません。これは、SDK を通じてデータをトラッキングするのではなく、たとえば Kameleoon エンジンによって管理されるクライアントサイドのトラッキングに依存する場合に便利です。さらに、`track=false` を設定することは、`get_variations()` メソッドを使用する場合に役立ちます。この場合、トラッキングイベントをトリガーすることなく、すべてのフラグのバリエーションだけが必要になる可能性があります。トラッキングの仕組みについて詳しく知りたい場合は、[この記事](/ja/developer-docs/feature-experimentation/technical-reference/faq-global#when-does-the-sdk-send-a-tracking-request-for-analytics) を参照してください。

##### ユーザーをターゲット化したり、レポートで訪問をフィルタリング/ブレークダウンするためのデータポイントの追加

ユーザーをターゲットにするには、フィーチャーバリエーションを取得したり、フラグがアクティブかどうかを確認したりする前に、関連するデータポイントをそのプロファイルに追加してください。これらのデータポイントをユーザーのプロファイルに追加するには、[`add_data()`](#add_data) メソッドを使用します。

他のデバイスで収集されたデータポイントを取得したり、過去のユーザーデータ(Kameleoon をハイブリッドモードで使用する場合、クライアントサイドで収集されたデータ)にアクセスしたりするには、[`get_remote_visitor_data()`](#get_remote_visitor_data) メソッドを使用します。このメソッドは、サーバーから非同期にデータを取得します。このデータは、ユーザーを特定のバリエーションに割り当てるために必要となる可能性があるため、バリエーションを取得したり、フィーチャーフラグがアクティブかどうかを確認する*前に* `get_remote_visitor_data()` を呼び出すことが重要です。

利用可能なターゲティング条件の詳細については、[このトピックに関する詳細な記事](/ja/developer-docs/feature-experimentation/targeting-and-segmentation/native-segmentation) を参照してください。

さらに、訪問者プロファイルに追加するデータポイントは、実験を分析するときに利用可能になり、デバイスやブラウザなどの要因で結果をフィルタリングしたり分解したりできます。Kameleoon のハイブリッドモードは、クライアントサイドでさまざまなデータポイントを自動的に収集するため、これらの事前に収集されたデータポイントに基づいて結果を簡単に分解できます。完全なリストは [こちら](/ja/user-manual/experiment-analytics/analyze-results/results-page/results-page-settings#オーディエンスの分割) を参照してください。

自動的に収集されるもの以外に追加のデータポイントを追跡する必要がある場合は、Kameleoon の [カスタムデータ機能](#customdata) を使用できます。カスタムデータを使用すると、実験に関連する特定の情報をキャプチャして分析できます。収集したデータを分析のために Kameleoon サーバーに送信するには、[`flush()`](#flush) メソッドを呼び出すことを忘れないでください。

<Note>
  結果の正確性を確保するため、[`UserAgent`](#useragent) データ型を使用してボットをフィルタリングすることをお勧めします。
</Note>

##### 目標コンバージョンのトラッキング

ユーザーが望ましいアクション(購入など)を完了すると、コンバージョンとして記録されます。コンバージョンを追跡するには、[`track_conversion()`](#track_conversion) メソッドを使用し、必要な `visitor_code` および `goal_id` パラメータを指定します。

コンバージョントラッキングリクエストは、SDK が定期的に送信する次のスケジュールされたトラッキングリクエスト([`tracking_interval_millis`](#追加の構成) で定義)と共に送信されます。リクエストを即座に送信したい場合は、[`flush_instant()`](#flush) メソッドを使用してください。

##### 分析ソリューションへのイベント送信

コンバージョンをトラッキングし、露出イベントを顧客分析ソリューションに送信するには、まず Kameleoon を [ハイブリッドモード](/ja/developer-docs/feature-experimentation/get-started/hybrid-experimentation) で実装する必要があります。その後、[`get_engine_tracking_code()`](#get_engine_tracking_code) メソッドを使用します。

`get_engine_tracking_code()` メソッドは、露出イベントを分析ソリューションに送信するために必要な一意のトラッキングコードを取得します。このメソッドを使用すると、イベントを記録し、希望の分析プラットフォームに送信できます。

### エラー処理

SDK が発生させるすべてのエラーは `KameleoonException` であるため、この型に対する単一のハンドラーで SDK のすべての失敗をキャッチできます。アプリケーションが特定の失敗に対応する必要がある場合は、特定のエラータイプを処理してください。たとえば、フィーチャーフラグが構成に含まれていない場合や SDK がまだ初期化されていない場合に、デフォルトの動作にフォールバックするなどです。各メソッドのリファレンスセクションに、発生する可能性のあるエラーが一覧表示されています。

`KameleoonException` は `std::runtime_error` から派生しています。エラーを区別する `ErrorCode` を取得するには `code()` を、メッセージを取得するには `what()` を呼び出します。

```cpp theme={null}
#include "kameleoon/kameleoon.hpp"

#include <iostream>

using namespace kameleoon;

try {
    Variation variation = client.get_variation(visitor_code, "new_checkout");
} catch (const KameleoonException& error) {
    switch (error.code()) {
    case ErrorCode::FeatureNotFound:
        // The feature flag isn't in the SDK configuration.
        break;
    case ErrorCode::Initialization:
        // The SDK isn't ready yet; fall back to your default behavior.
        break;
    default:
        std::cerr << "Kameleoon error: " << error.what() << "\n";
        break;
    }
}
```

| エラーコード | 説明 |
| - | - |
| `ErrorCode::Initialization` | クライアントを作成できなかった(空のサイトコード、構成の欠落または読み取り不可、空の認証情報)、SDK がまだ初期化されていない、または `initialize()` のタイムアウトが切れる前に初期化結果が得られなかったことを示します。 |
| `ErrorCode::FeatureNotFound` | 要求されたフィーチャーキーが SDK の内部構成に見つからなかったことを示す例外。これは通常、フィーチャーフラグが Kameleoon アプリでアクティブ化されていない(ただし、フィーチャーを実装するコードはすでにアプリケーションにデプロイされている)ことを意味します。 |
| `ErrorCode::FeatureExperimentNotFound` | 要求された実験 ID が SDK の内部構成に見つからなかったことを示す例外。これは通常正常であり、ルールの対応する実験が Kameleoon 側でまだアクティブ化されていないことを意味します。 |
| `ErrorCode::FeatureVariationNotFound` | 要求されたバリエーションキー(ID)が SDK の内部構成に見つからなかったことを示す例外。これは通常正常であり、バリエーションの対応する実験が Kameleoon 側でまだアクティブ化されていないことを意味します。 |
| `ErrorCode::FeatureEnvironmentDisabled` | フィーチャーフラグが訪問者の現在の環境(たとえば、production、staging、または development)で無効になっていることを示す例外。 |
| `ErrorCode::FeatureRuleNotFound` | 要求されたルールが SDK 構成に見つかりませんでした。 |
| `ErrorCode::FeatureEvaluationBlocked` | フィーチャー評価がブロックされていることを示す例外。理由はエラーメッセージに記述されています。これは通常、訪問者が法的同意を提供していない場合の GDPR 制限が原因で発生します。 |
| `ErrorCode::VisitorCodeInvalid` | 提供された訪問者コードが有効でないことを示す例外。空であるか、255 文字を超えています。 |
| `ErrorCode::InvalidSimVarCookieFormat` | `kameleoonSimulationFFData` クッキーに不正な形式の JSON が含まれており、シミュレートされたバリエーションを解析できないことを示します。 |
| `ErrorCode::InvalidArgument` | 引数が無効です。文字列が有効な UTF-8 でない、列挙値が不明、タイムアウトがゼロまたは負、または入力がサポートされる長さを超えています。 |
| `ErrorCode::Network` | ネットワークリクエストが失敗したか、サーバーが非成功ステータスコードで応答しました。構成のフェッチ、リモートデータまたはリモート訪問者データのリクエスト、またはウェアハウスオーディエンスのリクエストが対象です。`proxy_host` が無効なためにクライアントを作成できない場合にも返されます。 |
| `ErrorCode::Internal` | 予期しない SDK 内部エラー。たとえば、`libkameleoon_ffi` のバージョン不一致、ムーブ済みのクライアントに対するメソッド呼び出し、または構成に存在しないバリエーションキーなどです。 |

<Note>
  SDK に渡す文字列は有効な UTF-8 でなければなりません。SDK に提供するコールバック(`CookieAccessor` のオーバーライド、イベントハンドラー、ロガー)は例外をスローしてはいけません。コールバックから脱出した例外は SDK の境界でキャッチされ、破棄されます。
</Note>

<Note>
  SDK のエラーはクラッシュではなく、想定された動作です。まだアクティブ化されていないフィーチャーフラグ、構成をまだロード中の SDK、ネットワークの失敗はすべて正常な状態です。フィーチャー評価が失敗した場合は、エラーをログに記録し、訪問者が引き続き正常な体験を得られるようにデフォルトの動作にフォールバックしてください。
</Note>

### 非同期操作

ネットワークに依存する操作([`initialize()`](#initialize)、[`flush_instant()`](#flush)、[`get_remote_data()`](#get_remote_data)、[`get_remote_visitor_data()`](#get_remote_visitor_data)、および [`get_visitor_warehouse_audience()`](#get_visitor_warehouse_audience))は、SDK 独自のワーカースレッドで実行されます。それぞれ 3 つの形式があり、呼び出し元のスレッドに合ったものを選択できます:

| 形式 | 例 | 使用する場面 |
| - | - | - |
| ブロッキング | `client.initialize(timeout)` | スレッドが待機できる場合: 起動、シャットダウン、バッチジョブ、テスト。 |
| コンプリーション | `client.initialize_async(timeout, on_done)` | イベントループを実行している場合(C++17)。呼び出しは即座に戻り、`on_done` が結果を受け取ります。 |
| アウェイタブル | `co_await client.co_initialize(timeout)` | C++20 コルーチンを記述している場合。 |

```cpp theme={null}
// Blocking: waits until the data is fetched, throws a KameleoonException on failure.
client.get_remote_visitor_data(visitor_code);

// Completion: returns immediately; `error` is null on success.
client.get_remote_visitor_data_async(visitor_code, {}, [](std::exception_ptr error) {
    if (error) {
        // Rethrow `error` to get the KameleoonException.
        return;
    }
    // The remote data is now available locally.
});

// C++20 coroutine: throws a KameleoonException on failure.
co_await client.co_get_remote_visitor_data(visitor_code);
```

コンプリーションは `Completion<void>`(`std::function<void(std::exception_ptr)>`)、または値を返す操作の場合は `Completion<T>`(`std::function<void(std::exception_ptr, T)>`)です。SDK はこれを正確に 1 回呼び出します。コンプリーションを省略して、操作をファイアアンドフォーゲットで実行することもできます。その場合、失敗は SDK のログにのみ記録されます。

<Warning>
  コンプリーションとイベントハンドラーは通常 SDK のワーカースレッドで実行されますが、コンプリーションは、`*_async` の呼び出しが戻る前に、呼び出し元のスレッドで実行されることもあります。たとえば、SDK が即座に失敗する場合(クライアントが準備できていない、訪問者コードが無効)や、すでに初期化されたクライアントで `initialize_async()` が呼び出された場合です。コンプリーションが特定のスレッドで、または呼び出しが戻った後に実行されると想定しないでください。また、コンプリーションも取得するロックを呼び出しをまたいで保持しないでください。コンプリーションとイベントハンドラーはブロックしてはならず、例外をスローしてはならず、SDK 操作のブロッキング形式を呼び出してはいけません。同じワーカースレッドを待機してデッドロックするためです。結果を独自のイベントループに引き渡し、そこで処理を完了してください。
</Warning>

<Note>
  C++20 には組み込みのコルーチンタスク型がないため、`co_await` は、プロミス型が SDK の `Awaitable<T>` を受け入れるコルーチン内でのみ機能します(コルーチンが利用可能な場合、`KAMELEOON_HAS_COROUTINES` が `kameleoon/async.hpp` によって定義されます)。デフォルトでは、コルーチンは SDK のワーカースレッドで再開されます。代わりに独自のイベントループで再開するには、アウェイタブルの `.via(executor)` を呼び出します。Boost.Asio などの独自のコルーチン型を持つフレームワークでは、コンプリーション形式の周りに小さなアダプターが必要です。SDK に同梱されているサーバー例を参照してください。
</Note>

評価メソッド(`get_visitor_code()`、`get_variation()`、`get_variations()`、`is_feature_active()`、`add_data()`、`track_conversion()`、および `flush()`)は同期的なインメモリ呼び出しであり、これらは一切不要です。

### カスタムバケットキーの使用

デフォルトでは、Kameleoon は一意の匿名訪問者 ID(`visitor_code`)を使用して、ユーザーをフィーチャーフラグバリエーションに割り当てます。この ID は通常、ユーザーのデバイスで生成され保存されます(クライアントサイドおよびサーバーサイド SDK の場合はブラウザクッキー内、モバイル SDK の場合は永続ストレージ内)。ただし、特定のシナリオでは、同じ組織のすべてのユーザーがフィーチャーフラグの同じバリアントを参照することを確認する必要がある場合があります。

**カスタムバケットキー**オプションを使用すると、バケッティング用の独自のカスタム識別子を提供することで、このデフォルトの動作を上書きできます。このオーバーライドにより、Kameleoon の割り当てロジックがデフォルトの `visitor_code` の代わりに指定されたキーを使用するようになります。

#### ユースケース

カスタムバケットキーの使用は、特に次のような状況において、フィーチャーフラグ割り当ての一貫性と正確性を維持するために不可欠です。

* **アカウントレベルまたは組織の実験:** B2B 製品や、同じ組織のすべてのユーザーを同じバリエーションに割り当てたいシナリオでは、`account_id` のような識別子を使用できます。カスタムバケットキーは、チームや会社全体に影響を与える機能の A/B テストにとって極めて重要です。

カスタムバケットキーを実装することで、実験の一貫性と正確性が向上し、より信頼性の高い結果とより良いユーザーエクスペリエンスにつながります。

#### 技術的な詳細

フィーチャーフラグのカスタムバケットキーを構成するときは、アプリケーションのデータから特定の識別子を Kameleoon に提供します。

```cpp theme={null}
using namespace kameleoon;

client.add_data(visitor_code, {CustomData(42, {"new_visitor_code"})});
```

* **カスタムキーの提供:** [`add_data()`](#add_data) メソッドを使用して、カスタム識別子を Kameleoon SDK に提供します。このメソッドでは、選択したカスタムバケットキーを [`CustomData`](#customdata) オブジェクトとして渡します。ここで、`new_visitor_code` は、バケッティングに使用したい識別子(たとえば、新しい `user_id` または `account_id`)を指します。

<Warning>
  カスタムバケットキーが正しく機能するためには、フラグの作成または編集プロセス中に、フィーチャーフラグに対しても定義および構成される必要があります。これに対応する設定がないと、SDK のバケッティングはカスタムキーを適用しません。Kameleoon でこれを設定する方法の詳細については、この [記事](/ja/user-manual/experimentation/feature-experimentation/create-and-manage-flags/create-a-feature-flag) を参照してください。
</Warning>

* **バケッティングロジック:** `add_data()` メソッドを介してカスタムバケットキーが提供されると、ユーザーをバリエーションに割り当てるためのすべてのハッシュ計算は、デフォルトの `visitor_code` ではなく、この `new_visitor_code`(カスタムキー)を使用します。`new_visitor_code` を使用することは、バケッティングの決定がカスタム識別子に紐付けられることを意味し、その識別子が存在するさまざまなコンテキストにわたって一貫した割り当てを保証します。
* **データトラッキングと分析:** `new_visitor_code`(カスタムキー)がバケッティングの決定に使用される一方、**その後のすべてのデータ(たとえばトラッキングイベントやコンバージョン)は、*元の* `visitor_code` と共に送信および関連付けられる**ことに注意することが重要です。この分離により、バケッティングが上位レベル(アカウントなど)で実行されたり、複数のデバイス/セッションにまたがって実行されたりする場合でも、分析が個々のユーザージャーニーと、より広い実験コンテキスト内でのインタラクションを正確に反映するようになります。元の訪問者データは、包括的なレポートのために維持されます。

#### 技術要件

カスタムバケットキーを効果的に使用するには:

* キーは `std::string` でなければなりません。
* バケッティングの対象となるエンティティに対して一意でなければなりません(たとえば、`user_id` を使用する場合、各ユーザーの ID は一意である必要があります)。
* フィーチャーフラグの決定がそのユーザーまたはリクエストに対して評価される時点で、キーが SDK で利用可能でなければなりません。

### ターゲティング条件

Kameleoon SDK は、キャンペーンでユーザーをターゲットにするために使用できる、さまざまな事前定義されたターゲティング条件をサポートしています。この SDK がサポートする条件の一覧については、[訪問履歴を使用してユーザーをターゲットにする](/ja/developer-docs/feature-experimentation/targeting-and-segmentation/native-segmentation) を参照してください。

独自の [外部データを使用してユーザーをターゲット](/ja/developer-docs/apis/data-api-rest/tutorials/storing-and-retrieving-external-data-to-target-users) にすることもできます。

### クロスデバイス実験

複数のデバイスからアプリにアクセスする訪問者をサポートするため、Kameleoon ではクロスデバイス実験を通じて、以前に収集された訪問者データを訪問者の各デバイス間で同期し、デバイス間の訪問履歴を統合できます。Kameleoon がデバイス間でデータをどのように扱うかについてのケーススタディと詳細情報は、[クロスデバイス実験に関する記事](/ja/developer-docs/cross-device-experimentation) で入手できます。

#### デバイス間でのカスタムデータの同期

カスタムマッピング同期はデバイス間で訪問者データを揃えるために使用されますが、常に必要なわけではありません。以下は、カスタムマッピング同期が不要な 2 つのシナリオです。

**デバイス間で同じユーザー ID**
すべてのデバイスで同じユーザー ID が一貫して使用されている場合、カスタムマッピング同期なしに同期が自動的に処理されます。複数のデバイス間で収集されたデータを同期したい場合は、`get_remote_visitor_data()` メソッドを呼び出すだけで十分です。

**一貫した ID を持つマルチサーバーインスタンス**
複数のサーバー(たとえば、分散サーバーインスタンス)を含む複雑な設定で、サーバー間で同じユーザー ID が利用可能な場合、サーバー間の同期(`get_remote_visitor_data()` を使用)で十分で、追加のカスタムマッピング同期は不要です。

追加データが必要なお客様は、詳細なガイダンスについて [`get_remote_visitor_data()`](#get_remote_visitor_data) メソッドの説明を参照してください。以下のコードでは、正確なデータ取得のために、2 つのデバイス間で同じ一意の識別子(この場合は `visitor_code`、`userId` とも呼ばれます)が一貫して使用されていることを前提としています。

<Note>
  収集したデータをリアルタイムで同期したい場合は、カスタムデータのスコープに **Visitor** を選択する必要があります。
</Note>

```cpp title="Device A" theme={null}
// In this example, a Custom data with index `90` was set to "Visitor" scope in Kameleoon.
using namespace kameleoon;

constexpr uint32_t VISITOR_SCOPE_CUSTOM_DATA_INDEX = 90;

client.add_data(visitor_code, {CustomData(VISITOR_SCOPE_CUSTOM_DATA_INDEX, {"your data"})});

client.flush_instant(visitor_code);
```

```cpp title="Device B" theme={null}
// Before working with the data, call the `get_remote_visitor_data` method.
client.get_remote_visitor_data(visitor_code);

// After calling the method, the SDK on Device B will have access to CustomData of Visitor scope defined on Device A.
// So, "your data" will be available for targeting and tracking the visitor.
```

#### セッションマージのためのカスタムデータの使用

[クロスデバイス実験](/ja/developer-docs/cross-device-experimentation) を使用すると、訪問者の履歴を各デバイス間で結合できます(履歴の統合)。履歴の統合により、異なる訪問者セッションを 1 つにマージできます。訪問履歴を統合するには、[`CustomData`](#customdata) を使用して訪問者の一意の識別子を提供します。詳細については、[専用のドキュメント](/ja/developer-docs/cross-device-experimentation#クロスデバイス履歴の整合化を有効にする) を参照してください。

クロスデバイス統合が有効になった後、パラメータ `userId` を指定して [`get_remote_visitor_data()`](#get_remote_visitor_data) を呼び出すと、特定のユーザーに対するすべての既知のデータが取得されます。

同じ識別子を持つセッションは、実験において常に同じバリエーションが表示されます。実験結果ページの Visitor ビューでは、これらのセッションは単一の訪問者として表示されます。

SDK 構成により、関連するセッションは常に実験の同じバリエーションを参照することが保証されます。ただし、クロスデバイスのバリエーション割り当てに関するいくつかの制限があります。これらの制限の概要は、[クロスデバイス実験のドキュメント](/ja/developer-docs/cross-device-experimentation#重要なポイントと実践的な洞察) に記載されています。

Kameleoon プラットフォームでカスタムデータを設定するには、[クロスデバイス履歴統合の有効化](#クロスデバイス実験) ガイドに従ってください。

その後、SDK を通常通り使用できます。次のメソッドはセッションマージのコンテキストで役立つ可能性があります:

* `UniqueIdentifier(true)` を追加した `get_remote_visitor_data()` - リンクされたすべての訪問者のデータを取得します。
* `UniqueIdentifier(true)` データを追加した [`track_conversion()`](#track_conversion) または [`flush()`](#flush) - 別の訪問者に関連付けられた特定の訪問者のデータを追跡します。

<Tip>
  識別子として使用するカスタムデータは **Visitor スコープ** に設定する必要があるため、各デバイスで [`get_remote_visitor_data()`](#get_remote_visitor_data) メソッドを使用して識別子を取得するには、[クロスデバイスカスタムデータ同期](/ja/developer-docs/cross-device-experimentation) を使用する必要があります。
</Tip>

以下に、セッションマージのためのカスタムデータの使用例を示します。

```cpp theme={null}
// In this example, 91 represents the Custom Data's index configured as a unique identifier in Kameleoon.
using namespace kameleoon;

constexpr uint32_t MAPPING_INDEX = 91;
const std::string FEATURE_KEY = "ff123";

const std::string anonymous_visitor_code = "anonymous-visitor";
const std::string user_id = "authenticated-user";

// 1. Before the visitor is authenticated

// Retrieve the variation for an unauthenticated visitor.
// Assume anonymousVisitorCode is the randomly generated ID for that visitor.
Variation anonymous_variation = client.get_variation(anonymous_visitor_code, FEATURE_KEY);

// 2. After the visitor is authenticated

// Assume `userId` is the visitor code of the authenticated visitor.
client.add_data(anonymous_visitor_code, {CustomData(MAPPING_INDEX, {user_id})});
client.flush_instant(anonymous_visitor_code);

// Indicate that `userId` is a unique identifier.
client.add_data(user_id, {UniqueIdentifier{true}});

// 3. After the visitor was authorized

// Retrieve the variation for the `userId`, which will match the anonymous visitor code's variation.
Variation user_variation = client.get_variation(user_id, FEATURE_KEY);
bool is_same_variation = user_variation.key == anonymous_variation.key; // true

// `userId` and `anonymousVisitorCode` are now linked and can be tracked as a single visitor.
client.track_conversion(user_id, 123);

// Additionally, the linked visitors share all fetched previously tracked remote data.
client.get_remote_visitor_data(user_id);
```

この例では、アプリケーションにログインページがあります。ログイン時点ではユーザー ID が不明であるため、[`get_visitor_code()`](#get_visitor_code) メソッドによって生成された匿名訪問者識別子が使用されます。ユーザーがログインした後、匿名訪問者はユーザー ID に関連付けられ、訪問者の一意の識別子として使用されます。

### ロギング

SDK は、さまざまな内部プロセスや問題を反映するログを生成します。

#### ログレベル

SDK は、ログレベルによるロギングの制限の構成をサポートしています。

```cpp theme={null}
#include "kameleoon/logging.hpp"

using namespace kameleoon;

// The `None` log level does not allow logging.
KameleoonLogger::set_log_level(LogLevel::None);

// The `Error` log level only allows logging issues that may affect the SDK's primary behaviour.
KameleoonLogger::set_log_level(LogLevel::Error);

// The `Warning` log level allows logging issues which may require attention.
// It extends the `Error` log level.
// The `Warning` log level is the default log level.
KameleoonLogger::set_log_level(LogLevel::Warning);

// The `Info` log level allows logging general information on the SDK's internal processes.
// It extends the `Warning` log level.
KameleoonLogger::set_log_level(LogLevel::Info);

// The `Debug` level logs additional details about the SDK's internal processes and extends the `Info` level
// with more granular diagnostic output.
// This information is not intended for end-user interpretation but can be sent to our support team
// to assist with internal troubleshooting.
KameleoonLogger::set_log_level(LogLevel::Debug);
```

#### ログのカスタムハンドリング

SDK はデフォルトでログをコンソール出力に書き込みます。この動作はオーバーライドできます。

<Note>
  ログレベルによるロギング制限は、ログハンドリングロジックとは別に実行されます。
</Note>

```cpp theme={null}
#include "kameleoon/logging.hpp"

#include <spdlog/spdlog.h>

using namespace kameleoon;

// Log level filtering is applied separately from log handling logic.
// The custom logger will only receive logs that meet or exceed the specified log level.
// Ensure the log level is set correctly.
KameleoonLogger::set_log_level(LogLevel::Debug); // Optional; defaults to `LogLevel::Warning`.

// The logger is any callable accepting the log level and the message.
// It may be invoked from SDK threads, so it must be thread-safe and must not throw.
KameleoonLogger::set_logger([](LogLevel level, const std::string& message) {
    switch (level) {
    case LogLevel::Error:   spdlog::error(message); break;
    case LogLevel::Warning: spdlog::warn(message); break;
    case LogLevel::Info:    spdlog::info(message); break;
    case LogLevel::Debug:   spdlog::debug(message); break;
    case LogLevel::None:    break;
    }
});

// Passing an empty logger restores the default logger of the SDK, which writes to stdout.
KameleoonLogger::set_logger({});
```

## リファレンス

これは C++ SDK の完全なリファレンスドキュメントです。

### 初期化

#### create()

SDK を使用するには、`KameleoonClientFactory::create()` を使用して、`KameleoonClientConfig` 構造体または JSON 構成ファイルから `KameleoonClient` を作成します。

クライアントはサイトコードと環境ごとにキャッシュされます。同じサイトコードと環境で `create()` を繰り返し呼び出すと、同じ基盤 SDK インスタンス上のクライアントが返され、最初の呼び出しの構成が優先されます。

<Tabs>
  <Tab title="create(config struct)">
    ```cpp theme={null}
    #include "kameleoon/kameleoon.hpp"

    using namespace kameleoon;

    KameleoonClientConfig config{
        .client_id = "<client-id>",                  // mandatory
        .client_secret = "<client-secret>",          // mandatory
        .refresh_interval_minutes = 60,              // optional (60 minutes by default)
        .session_duration_minutes = 30,              // optional (30 minutes by default)
        .default_timeout_millis = 10'000,            // optional (10000 ms by default)
        .tracking_interval_millis = 1'000,           // optional (1000 ms by default)
        .proxy_host = "http://192.168.0.25:8080",    // optional
        .environment = "development",                // optional
        .top_level_domain = ".example.com",          // mandatory if you use hybrid mode (engine or web experiments)
        .network_domain = "example.com",             // optional
    };

    KameleoonClient client = KameleoonClientFactory::create(site_code, config);
    ```

    ##### パラメーター

    | 名前 | 型 | 説明 |
    | - | - | - |
    | `site_code` <Badge color="red" size="sm">必須</Badge> | `std::string` | SDK が使用する Kameleoon プロジェクトの一意のキー。 |
    | `config` <Badge color="red" size="sm">必須</Badge> | `KameleoonClientConfig` | SDK 構成構造体。 |
  </Tab>

  <Tab title="create(config file)">
    ```cpp theme={null}
    #include "kameleoon/kameleoon.hpp"

    using namespace kameleoon;

    KameleoonClient client = KameleoonClientFactory::create("a8st4f59bj", "/etc/kameleoon/client-cpp.json");
    ```

    ##### パラメーター

    | 名前 | 型 | 説明 |
    | - | - | - |
    | `site_code` <Badge color="red" size="sm">必須</Badge> | `std::string` | SDK が使用する Kameleoon プロジェクトの一意のキー。 |
    | `config_path` <Badge color="red" size="sm">必須</Badge> | `std::string` | JSON 構成ファイルへのパス。 |
  </Tab>
</Tabs>

##### 戻り値

| 型 | 説明 |
| - | - |
| `KameleoonClient` | クライアントインスタンス。[`initialize()`](#initialize) が完了するまで、クライアントはフィーチャーフラグを評価する準備ができていません。 |

##### 例外

| 型 | 説明 |
| - | - |
| `ErrorCode::Initialization` | サイトコードが空、`client_id` または `client_secret` が空、または構成ファイルを読み取りまたは解析できません。エラーメッセージに正確な原因が示されます。 |
| `ErrorCode::Internal` | ロードされた `libkameleoon_ffi` ライブラリが、SDK のビルド時のバージョンと一致しません。 |

#### initialize()

アプリケーションがフィーチャーフラグを評価する前に Kameleoon クライアントの初期化完了を待つ必要がある場合は、`initialize()` を使用します。

この呼び出しは構成フェッチの結果を返します。クライアントの初期化が完了すると正常に完了し、クライアントが準備できる前に初回の構成フェッチが失敗すると失敗します。その最初の失敗の後も、バックグラウンドでの再試行は継続されます。再試行が成功すると、以降の呼び出しは成功した結果を返します。タイムアウトが切れる前に初期化結果が得られない場合、呼び出しは失敗します。`timeout` 値を提供しない場合、SDK は [`default_timeout_millis`](#追加の構成) のデフォルトタイムアウトを使用します。

<Tip>
  アプリケーションの起動時に `initialize()` を 1 回呼び出し、SDK が構成をロードするかタイムアウトが切れるまで待機します。各受信リクエストでは、フィーチャーフラグを評価する前のノンブロッキングなガードとして [`is_ready()`](#is_ready) を使用してください。`initialize()` が失敗しても、SDK はバックグラウンドで構成のフェッチを再試行し続けるため、再試行が成功すると `is_ready()` は `true` を返すようになります。
</Tip>

```cpp theme={null}
#include <chrono>

// Initializes the client using the configured default timeout (blocking).
client.initialize();

// Initializes the client with a custom timeout of 5 seconds (blocking).
client.initialize(std::chrono::seconds(5));

// Initializes the client without blocking; the completion receives the outcome.
client.initialize_async(std::chrono::seconds(5), [](std::exception_ptr error) {
    if (error) {
        // Initialization failed: rethrow `error` to get the `KameleoonException`.
        return;
    }
    // The client is ready.
});

// C++20 coroutines
co_await client.co_initialize(std::chrono::seconds(5));
```

##### パラメーター

| 名前 | 型 | 説明 | デフォルト |
| - | - | - | - |
| `timeout` <Badge color="green" size="sm">任意</Badge> | `std::optional<std::chrono::milliseconds>` | 初期化結果を待つ最大時間。 | `default_timeout_millis` |

##### 戻り値

| 型 | 説明 |
| - | - |
| `void` | SDK の準備ができると戻ります。初回の構成フェッチが失敗した場合、またはタイムアウトが切れる前に初期化結果が得られない場合は、`KameleoonException` をスローします。 |

##### 例外

| 型 | 説明 |
| - | - |
| `ErrorCode::Initialization` | タイムアウトが切れる前に初期化結果が得られませんでした。 |
| `ErrorCode::Network` | ネットワークエラーまたは予期しない HTTP ステータスにより、構成の初回フェッチが失敗しました。SDK はバックグラウンドで再試行し続けるため、再試行が成功すると後続の呼び出しは成功します。 |
| `ErrorCode::InvalidArgument` | 提供された `timeout` がゼロまたは負です。 |

#### is\_ready()

`is_ready()` は、SDK が使用可能な状態、つまり構成が正常にロードされているかどうかを確認します。[`initialize()`](#initialize) とは異なり、このメソッドはブロックやスローをせずに即座に戻ります。

<Tip>
  * SDK は一度準備が完了すると、その状態を維持します。その後の構成リフレッシュが失敗しても、SDK は以前にダウンロードした構成を使用し続け、未準備の状態に戻ることはありません。
  * アプリケーションの起動時に `initialize()` を 1 回呼び出し、SDK が構成をロードするかタイムアウトが切れるまで待機します。各受信リクエストでは、フィーチャーフラグを評価する前のノンブロッキングなガードとして [`is_ready()`](#is_ready) を使用してください。`initialize()` が失敗しても、SDK はバックグラウンドで構成のフェッチを再試行し続けるため、再試行が成功すると `is_ready()` は `true` を返すようになります。
</Tip>

```cpp theme={null}
if (client.is_ready()) {
    // The client is ready
}
```

##### 戻り値

| 型 | 説明 |
| - | - |
| `bool` | SDK が正常に初期化されている場合は `true`、それ以外は `false`(初期化がまだ保留中または失敗した場合を含む)。 |

#### forget()

指定された `site_code` に関連付けられたキャッシュされた SDK クライアントを削除し、同じサイトコードと環境での次の `create()` 呼び出しで新しいクライアントが作成されるようにします。

`forget()` はファクトリの参照を破棄するだけです。そのサイトコード用に作成されたすべての `KameleoonClient` は、破棄されるまで基盤となる SDK インスタンス(およびそのワーカースレッド、ポーリング、トラッキング)を保持し、未完了の非同期操作は、そのコンプリーションが完了するまでインスタンスを保持します。バックグラウンドリソースを解放するには、`forget()` を呼び出し、そのサイトコードのすべての `KameleoonClient` インスタンスを破棄してください。

```cpp theme={null}
using namespace kameleoon;

// Removes the cached client created for the given site code without an environment
KameleoonClientFactory::forget("a8st4f59bj");

// Removes the cached client for the given site code and environment
KameleoonClientFactory::forget("a8st4f59bj", "production");
```

##### パラメーター

| 名前 | 型 | 説明 |
| - | - | - |
| `site_code` <Badge color="red" size="sm">必須</Badge> | `std::string` | Kameleoon プロジェクトの一意の識別子。 |
| `environment` <Badge color="green" size="sm">任意</Badge> | `std::string` | クライアントの作成時に使用された環境。`environment` を指定して作成されたクライアントは、同じ値がここに渡された場合にのみ削除されます。 |

### フィーチャーフラグとバリエーション

#### is\_feature\_active()

* 📨 *Kameleoon にトラッキングデータを送信します(`track` オプションに応じて)*

特定のユーザーに対してフィーチャーフラグがアクティブかどうかを判断します。

訪問者がこのフィーチャーフラグに対してまだ評価されていない場合、SDK はターゲティングルールを評価して結果を返します。訪問者がすでに保存された評価を持っている場合、SDK は一貫性を確保するために既存の結果を再利用します。

<Note>
  Kameleoon は、`is_feature_active()`、`get_variation()` または `get_variations()` などの特定のメソッドを呼び出すときに、トラッキングを使用してセッションと訪問者をカウントします。

  訪問者をバリエーションに公開し、それらをカウントする必要がある場合は、`track` パラメータにデフォルトの `true` 値を使用してください。訪問者を公開する前にこれらのメソッドを呼び出す場合のみ、`track` パラメータを `false` に設定してください。

  たとえば、訪問者を公開する前にすべてのバリエーションを取得するために `get_variations()` を呼び出す場合、`track` パラメータを `false` に設定してください。この設定により、Kameleoon がセッションを早期にカウントするのを防ぎます。後で訪問者を明示的に公開するときにトラッキングをトリガーできます。

  Kameleoon はデフォルトで毎秒トラッキングデータを送信します。tracking interval 構成オプションを使用して、この間隔を最大 5 秒まで設定できます。Kameleoon は、イベント間の間隔が 30 分未満である限り、トラッキングイベントを単一セッションにグループ化します。トラッキングイベント間に 30 分以上経過した場合、Kameleoon はイベントを別々のセッションとしてカウントします。訪問はセッションで最後に記録されたイベントから 30 分後にレポートに表示されます。
</Note>

<Warning>
  `is_feature_active()` メソッドは、マスターフラグ状態ではなく、提供されたバリアントを評価します。ルールを除外した場合、メソッドは **その他すべてに対して提供する** デフォルト状態を使用します。このデフォルト状態に **Off** を選択した場合、マスターフィーチャーフラグが **On** であってもメソッドは常に `false` を返します。
</Warning>

```cpp theme={null}
using namespace kameleoon;

const std::string feature_key = "new_checkout";

// Evaluates the feature flag and sends tracking data (default behavior)
bool active = client.is_feature_active(visitor_code, feature_key);

// Evaluates the feature flag without sending tracking data
bool active_without_tracking = client.is_feature_active(
    visitor_code, feature_key, IsFeatureActiveOptions{.track = false});
```

##### パラメーター

| 名前 | 型 | 説明 | デフォルト |
| - | - | - | - |
| `visitor_code` <Badge color="red" size="sm">必須</Badge> | `std::string` | ユーザーの一意の識別子。 | |
| `feature_key` <Badge color="red" size="sm">必須</Badge> | `std::string` | ユーザーに対して評価するフィーチャーのキー。 | |
| `options` <Badge color="green" size="sm">任意</Badge> | `IsFeatureActiveOptions` | フィーチャー評価のトラッキングを有効または無効にする単一の `track` フィールド(`bool`)を持つオプション構造体。 | `track = true` |

##### 戻り値

| 型 | 説明 |
| - | - |
| `bool` | 指定された `visitor_code` に対してフィーチャーフラグがアクティブかどうかを示します。 |

##### 例外

| 型 | 説明 |
| - | - |
| `ErrorCode::Initialization` | SDK がまだ完全に初期化されていないことを示します。 |
| `ErrorCode::FeatureNotFound` | 要求されたフィーチャーキーが SDK の内部構成に見つからなかったことを示す例外。これは通常、フィーチャーフラグが Kameleoon アプリでアクティブ化されていない(ただし、フィーチャーを実装するコードはすでにアプリケーションにデプロイされている)ことを意味します。 |
| `ErrorCode::VisitorCodeInvalid` | 提供された訪問者コードが有効でないことを示す例外。空であるか、255 文字を超えています。 |

#### get\_variation()

* 📨 *Kameleoon にトラッキングデータを送信します(`track` パラメータに応じて)*

特定のフィーチャーフラグに対して、指定された訪問者に割り当てられた [`Variation`](#variation) を取得します。

このメソッドは、`visitor_code` と `feature_key` を必須引数として受け取ります。`track` 引数はオプションで、デフォルトは `true` です。

訪問者に割り当てられた `Variation` を返します。訪問者がどのフィーチャーフラグルールにも関連付けられていない場合、メソッドは指定されたフィーチャーフラグのデフォルト `Variation` を返します。

潜在的な例外を管理するため、コード内で適切なエラー処理を実装してください。

<Note>
  デフォルトバリエーションとは、訪問者がフィーチャーフラグの事前定義された配信ルールのいずれにも一致しない場合に割り当てられるバリエーションのことです。言い換えると、特定のルールでターゲット指定されていないすべてのユーザーに適用されるフォールバックバリエーションです。管理インターフェイスの「その他すべてのユーザーには...」セクションのバリエーションとして表されます。
</Note>

```cpp theme={null}
using namespace kameleoon;

const std::string feature_key = "new_checkout";

// Retrieves the variation assigned to the visitor (with tracking enabled by default)
Variation variation = client.get_variation(visitor_code, feature_key);

// Retrieves the variation without sending tracking data
Variation variation_without_tracking = client.get_variation(
    visitor_code, feature_key, GetVariationOptions{.track = false});
```

##### パラメーター

| 名前 | 型 | 説明 | デフォルト |
| - | - | - | - |
| `visitor_code` <Badge color="red" size="sm">必須</Badge> | `std::string` | 訪問者の一意の識別子。 | |
| `feature_key` <Badge color="red" size="sm">必須</Badge> | `std::string` | 訪問者に公開したいフィーチャーのキー。 | |
| `track` <Badge color="green" size="sm">任意</Badge> | `bool` | フィーチャー評価のトラッキングを有効または無効にするオプションのパラメータ。 | `true` |

<Note>
  オプションの `track` パラメータは、`GetVariationOptions` 構造体の `track` フィールドとして渡されます。
</Note>

##### 戻り値

| 型 | 説明 |
| - | - |
| `Variation` | 特定のフィーチャーフラグに対して指定された訪問者に割り当てられた [`Variation`](#variation)。 |

##### 例外

| 型 | 説明 |
| - | - |
| `ErrorCode::Initialization` | SDK がまだ完全に初期化されていないことを示します。 |
| `ErrorCode::VisitorCodeInvalid` | 提供された訪問者コードが有効でないことを示す例外。空であるか、255 文字を超えています。 |
| `ErrorCode::FeatureNotFound` | 要求されたフィーチャーキーが SDK の内部構成に見つからなかったことを示す例外。これは通常、フィーチャーフラグが Kameleoon アプリでアクティブ化されていない(ただし、フィーチャーを実装するコードはすでにアプリケーションにデプロイされている)ことを意味します。 |
| `ErrorCode::FeatureEnvironmentDisabled` | フィーチャーフラグが訪問者の現在の環境(たとえば、production、staging、または development)で無効になっていることを示す例外。 |
| `ErrorCode::FeatureEvaluationBlocked` | フィーチャー評価がブロックされていることを示す例外。理由はエラーメッセージに記述されています。これは通常、訪問者が法的同意を提供していない場合の GDPR 制限が原因で発生します。 |

#### get\_variations()

* 📨 *Kameleoon にトラッキングデータを送信します(`track` パラメータに依存)*

すべてのフィーチャーフラグにわたって、指定された訪問者に割り当てられた [`Variation`](#variation) オブジェクトのマップを取得します。

このメソッドは、利用可能なすべてのフィーチャーフラグを反復処理し、指定された訪問者に関連付けられた各フラグに割り当てられた `Variation` を返します。`visitor_code` を必須引数として受け取り、`only_active` と `track` は任意です。

* `only_active` を `true` に設定すると、`get_variations()` メソッドは、訪問者が `off` バリエーションにバケット化されていない場合にのみフィーチャーフラグのバリエーションを返します。
* `track` パラメータは、メソッドがバリエーションの割り当てをトラッキングするかどうかを制御します。デフォルトでは `true` です。`false` の場合、メソッドはバリエーションの割り当てをトラッキングしません。

返されるマップは、フィーチャーフラグのキーをキーとし、対応する `Variation` を値として構成されます。SDK がフィーチャーフラグにバリエーションを割り当てない場合、メソッドはそのフラグのデフォルトの `Variation` を返します。

潜在的な例外を管理するために、適切なエラー処理を実装してください。

<Note>
  デフォルトバリエーションとは、フィーチャーフラグの事前定義された配信ルールのいずれにも一致しない訪問者に割り当てられるバリエーションを指します。言い換えれば、特定のルールの対象にならないすべてのユーザーに適用されるフォールバックバリエーションです。管理インターフェースの「Then, for everyone else...」セクションのバリエーションとして表されます。
</Note>

```cpp theme={null}
using namespace kameleoon;

// Retrieves all variations assigned to the visitor (with default options)
std::unordered_map<std::string, Variation> variations = client.get_variations(visitor_code);

// Retrieves only active variations for the visitor
auto only_active_variations = client.get_variations(
    visitor_code, GetVariationsOptions{.only_active = true});

// Retrieves variations without sending tracking data
auto variations_without_tracking = client.get_variations(
    visitor_code, GetVariationsOptions{.track = false});
```

##### パラメーター

| 名前 | 型 | 説明 | デフォルト |
| - | - | - | - |
| `visitor_code` <Badge color="red" size="sm">必須</Badge> | `std::string` | 訪問者の一意の識別子。 | |
| `only_active` <Badge color="green" size="sm">任意</Badge> | `bool` | アクティブな(`true`)フィーチャーフラグのバリエーションを返すか、すべての(`false`)フィーチャーフラグのバリエーションを返すかを示すオプションのパラメータ。 | `false` |
| `track` <Badge color="green" size="sm">任意</Badge> | `bool` | フィーチャー評価のトラッキングを有効または無効にするオプションのパラメータ。 | `true` |

<Note>
  オプションの `only_active` および `track` パラメータは、`GetVariationsOptions` 構造体のフィールドとして渡されます。
</Note>

##### 戻り値

| 型 | 説明 |
| - | - |
| `std::unordered_map<std::string, Variation>` | 対応するフィーチャーのキーを使用して、フィーチャーフラグの割り当てられた [`Variation`](#variation) オブジェクトを含むマップ。 |

##### 例外

| 型 | 説明 |
| - | - |
| `ErrorCode::Initialization` | SDK がまだ完全に初期化されていないことを示します。 |
| `ErrorCode::VisitorCodeInvalid` | 提供された訪問者コードが有効でないことを示す例外。空であるか、255 文字を超えています。 |

#### set\_forced\_variation()

このメソッドを使用すると、標準の評価プロセスをバイパスして、特定の [`Variation`](#variation) をユーザーにプログラムで割り当てることができます。このメソッドは、通常の評価ロジックが不要な場合やスキップする必要がある制御された実験で特に役立ちます。また、デバッグやカスタムテストのようなシナリオでも役立ちます。

**強制**バリエーションを設定すると、Kameleoon のリアルタイム評価ロジックがオーバーライドされます。SDK は、セグメンテーション、ターゲティング条件、アルゴリズム計算などのプロセスをスキップします。実験中にセグメンテーションとターゲティング条件を保持するには、代わりに `force_targeting=false` を設定してください。

<Info>
  **シミュレート**されたバリエーションは、実行順序において常に優先されます。**シミュレート**されたバリエーションの計算が開始されると、SDK はまずそれを完全に処理して完了させます。
</Info>

Kameleoon は、強制バリエーションを評価されたバリエーションと同じように扱います。標準的な評価済みバリエーションと同様に、分析でトラッキングされ、ユーザーコンテキストに保存されるため、レポートの一貫性が確保されます。

このメソッドは、特定の条件下(たとえば、無効なパラメータ、ユーザーコンテキスト、または内部の問題)で例外をスローする場合があります。アプリの安定性と回復力を確保するために、適切な例外処理が不可欠です。

<Warning>
  **強制**バリエーションと **[シミュレート](#get_visitor_code)** されたバリエーションを区別することが重要です:

  * **強制バリエーション**: 個々の実験に固有です。
  * **シミュレートされたバリエーション**: **フィーチャーフラグ**全体の結果に影響します。
</Warning>

```cpp theme={null}
using namespace kameleoon;

const uint32_t experiment_id = 202387;

// Forces the visitor into "variation_2" for the given experiment
client.set_forced_variation(visitor_code, experiment_id, "variation_2");

// Removes any previously forced variation for the visitor in this experiment
client.set_forced_variation(visitor_code, experiment_id, std::nullopt);

// Forces the visitor into "variation_2" with custom options
// In this case, targeting rules are respected (force_targeting = false)
client.set_forced_variation(
    visitor_code, experiment_id, "variation_2", SetForcedVariationOptions{.force_targeting = false});
```

##### パラメーター

| 名前 | 型 | 説明 | デフォルト |
| - | - | - | - |
| `visitor_code` <Badge color="red" size="sm">必須</Badge> | `std::string` | 訪問者の一意の識別子。 | |
| `experiment_id` <Badge color="red" size="sm">必須</Badge> | `uint32_t` | 評価プロセス中に SDK がターゲットとして選択する**実験 ID**。 | |
| `variation_key` <Badge color="red" size="sm">必須</Badge> | `std::optional<std::string>` | SDK が実験の戻り値として強制する `Variation` に対応する**バリエーションキー**。値が `std::nullopt` の場合、強制バリエーションはリセットされます。 | |
| `force_targeting` <Badge color="green" size="sm">任意</Badge> | `bool` | SDK が実験のターゲティングを強制的にスキップするか(`true`)、標準の評価プロセスと同様に適用するか(`false`)を示します。 | `true` |

<Note>
  オプションの `force_targeting` パラメータは、`SetForcedVariationOptions` 構造体の `force_targeting` フィールドとして渡されます。
</Note>

##### 例外

| 型 | 説明 |
| - | - |
| `ErrorCode::Initialization` | SDK がまだ完全に初期化されていないことを示します。 |
| `ErrorCode::VisitorCodeInvalid` | 提供された訪問者コードが有効でないことを示す例外。空であるか、255 文字を超えています。 |
| `ErrorCode::FeatureExperimentNotFound` | 要求された実験 ID が SDK の内部構成に存在しないことを示す例外。この動作は通常正常であり、ルールに対応する実験が Kameleoon 側でまだアクティブになっていないことを意味します。 |
| `ErrorCode::FeatureVariationNotFound` | 要求されたバリエーションキー(ID)が SDK の内部構成に存在しないことを示す例外。この動作は通常正常であり、バリエーションに対応する実験が Kameleoon 側でまだアクティブになっていないことを意味します。 |

#### evaluate\_audiences()

* 📨 *Kameleoon にトラッキングデータを送信します*

このメソッドは、利用可能なすべての Audiences Explorer セグメントに対して訪問者を評価し、一致した訪問者をトラッキングします。

`evaluate_audiences()` は、**関連するすべての訪問者データを設定または更新した後**、かつフィーチャーバリエーションの取得やフィーチャーフラグのチェックの**直前**に呼び出してください。このアプローチにより、Kameleoon は利用可能な最新のデータに対して訪問者を評価し、すべての基準に基づいた正確なオーディエンス割り当てが可能になります。

このメソッドを呼び出した後、Audiences Explorer でセグメントのパフォーマンスの詳細な分析を実行できます。

```cpp theme={null}
client.evaluate_audiences(visitor_code);
```

##### パラメーター

| 名前 | 型 | 説明 |
| - | - | - |
| `visitor_code` <Badge color="red" size="sm">必須</Badge> | `std::string` | 訪問者の一意の識別子。 |

##### 例外

| 型 | 説明 |
| - | - |
| `ErrorCode::Initialization` | SDK がまだ完全に初期化されていないことを示します。 |
| `ErrorCode::VisitorCodeInvalid` | 提供された訪問者コードが有効でないことを示す例外。空であるか、255 文字を超えています。 |

<Info>
  ほとんどの場合、例に示すように、基本的なエラーである `KameleoonException` を処理するだけで十分です。ただし、異なる種類のエラーに対応が必要な場合は、特定の要件に基づいてそれぞれを個別に処理してください。さらに、信頼性を高めるために、`std::exception` を含めることで一般的な言語エラーを処理できます。
</Info>

#### get\_datafile()

<Tip>
  すべてのフィーチャーフラグを評価するには、[`get_variations()`](#get_variations) を使用してください。このメソッドは、`DataFile` を呼び出して [`get_variation()`](#get_variation) でフラグを反復処理するよりも効率的です。
</Tip>

現在の SDK 構成を [`DataFile`](#datafile) オブジェクトとして返します。

返される `DataFile` は現在の構成のコピーです。SDK が構成を更新しても変更されません。

```cpp theme={null}
using namespace kameleoon;

DataFile datafile = client.get_datafile();
```

##### 戻り値

| 型 | 説明 |
| - | - |
| `DataFile` | SDK 構成を含む [`DataFile`](#datafile) |

##### 例外

| 型 | 説明 |
| - | - |
| `ErrorCode::Initialization` | SDK がまだ完全に初期化されていないことを示します。 |

### 訪問者データ

#### get\_visitor\_code()

`get_visitor_code()` を使用して、現在の訪問者の Kameleoon `visitor_code` を取得します。このメソッドは、`CookieAccessor` インターフェースを実装する任意の Cookie ストアで動作します。

実装ロジックは次のとおりです:

1. SDK は、提供されたアクセサを通じて `kameleoonVisitorCode` Cookie がすでに利用可能かどうかを確認します。
2. Cookie が存在しない場合、`default_visitor_code` を提供していれば、SDK はそれを使用します。
3. それ以外の場合、SDK は新しい訪問者コードを生成し、アクセサを通じて保存します。

詳細については、[ハイブリッド実験](/ja/developer-docs/feature-experimentation/get-started/hybrid-experimentation/)を参照してください。

<Warning>
  独自の `visitor_code` を提供する場合、その一意性はお客様側で保証する必要があります。また、`visitor_code` の長さは `255` 文字に制限されていることに注意してください。
</Warning>

<Info>
  `get_visitor_code()` メソッドを使用すると、訪問者に**シミュレート**されたバリエーションを設定できます。Cookie(**リクエスト**または**ドキュメント**から)にキー `kameleoonSimulationFFData` が含まれている場合、メソッドは Cookie を読み取り、その訪問者のシミュレートされたバリエーションを保存します。戻り値は変わりません。その後、[`get_variation()`](#get_variation) や [`is_feature_active()`](#is_feature_active) などのその訪問者に対するフィーチャー評価は、標準の評価プロセスをバイパスし、提供されたデータに基づいてシミュレートされた [`Variation`](#variation) を返します。

  シミュレーションは 2 つの方法で適用できます:

  * **自動(推奨):** Kameleoon Web Experimentation または[ハイブリッドモード](/ja/developer-docs/feature-experimentation/get-started/hybrid-experimentation#フィーチャー実験をフロントエンドのトラッキングコードとリンクする)で SDK を使用している場合、[シミュレーションパネル](/ja/user-manual/experimentation/feature-experimentation/using-the-rollout-planner/validation-and-rollback/using-simulation-mode)を使用してバリアントの表示をシミュレートすると、Kameleoon は自動的に Cookie を作成します。
  * **手動:** `kameleoonSimulationFFData` Cookie を手動で設定します。

  **シミュレート**されたバリエーションと\*\*[強制](#set_forced_variation)\*\*バリエーションを区別することが重要です:

  * **シミュレートされたバリエーション**: **フィーチャーフラグ**全体の結果に影響します。
  * **強制バリエーション**: 個々の実験に固有です。

  ⚙️ **手動設定**

  `kameleoonSimulationFFData` Cookie が次の形式に従っていることを確認してください:

  * `kameleoonSimulationFFData={"featureKey":{"expId":10,"varId":20}}`: 指定された `featureKey` に対して、実験 `expId` の `varId` のバリエーションをシミュレートします。
  * `kameleoonSimulationFFData={"featureKey":{"expId":0}}`: 指定された `featureKey` に対して、デフォルトバリエーション(**Then, for everyone else in Production, serve** セクションで定義)をシミュレートします。

  ⚠️ Cookie 値が正しく機能するようにするには、[`encodeURIComponent`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent) などのメソッドを使用して URI コンポーネントとしてエンコードしてください。
</Info>

##### `CookieAccessor` インターフェース

`kameleoon::CookieAccessor` を実装して、SDK の Cookie の読み取りと書き込みを HTTP フレームワークに橋渡しします:

| メソッド | 説明 |
| - | - |
| `std::optional<std::string> get(const std::string& key)` | `key` の Cookie 値を返します。Cookie が存在しない場合は `std::nullopt` を返します。 |
| `void set(const std::string& key, const std::string& value, uint32_t max_age, std::optional<std::string> top_level_domain)` | `max_age`(秒単位)と、存在する場合は Cookie のドメインとして `top_level_domain` を使用して、レスポンスに Cookie を保存します。 |

<Note>
  * `get()` は、同じ名前のリクエスト Cookie よりも、レスポンスで `set()` を通じてすでに書き込まれた Cookie を優先して返す必要があります。SDK は呼び出し間で Cookie の状態を保持しないため、これにより、同じリクエスト内での 2 回目の `get_visitor_code()` 呼び出しが、新しいコードを生成するのではなく、1 回目の呼び出しで書き込まれたコードを返すようになります。
  * オーバーライドは SDK 内部から呼び出されるため、例外をスローしてはいけません。`get()` から漏れた例外は、Cookie が存在しないものとして扱われます。Cookie 値は有効な UTF-8 である必要があります。
</Note>

<Tabs>
  <Tab title="Custom">
    ```cpp theme={null}
    #include "kameleoon/kameleoon.hpp"

    #include <optional>
    #include <string>
    #include <unordered_map>

    using namespace kameleoon;

    // A cookie accessor over the cookies of an HTTP request. Cookies written by the
    // SDK are collected in `response_` and must be emitted as `Set-Cookie` headers.
    class RequestCookies final : public CookieAccessor {
    public:
        explicit RequestCookies(std::unordered_map<std::string, std::string> request)
            : request_(std::move(request)) {}

        void set(const std::string& key, const std::string& value, uint32_t max_age,
                 std::optional<std::string> top_level_domain) override {
            response_[key] = value;
            // Emit a `Set-Cookie` header with `max_age` and `top_level_domain` here.
        }

        std::optional<std::string> get(const std::string& key) override {
            // Prefer a cookie already written to the response in this request.
            if (const auto it = response_.find(key); it != response_.end()) return it->second;
            if (const auto it = request_.find(key); it != request_.end()) return it->second;
            return std::nullopt;
        }

    private:
        std::unordered_map<std::string, std::string> request_;
        std::unordered_map<std::string, std::string> response_;
    };

    RequestCookies cookies{parse_request_cookies(request)};

    // Generate or retrieve a visitor code using an auto-generated value
    std::string visitor_code = client.get_visitor_code(cookies);
    // Generate or retrieve a visitor code using a predefined user ID
    std::string visitor_code_with_default = client.get_visitor_code(cookies, "user_id");
    ```
  </Tab>

  <Tab title="Drogon">
    ```cpp theme={null}
    #include "kameleoon/kameleoon.hpp"

    #include <drogon/drogon.h>

    #include <map>
    #include <optional>
    #include <string>

    using namespace kameleoon;

    // Reads cookies from the request Drogon already parsed and collects the
    // SDK's cookies for the response.
    class DrogonCookieAccessor final : public CookieAccessor {
    public:
        explicit DrogonCookieAccessor(const drogon::HttpRequestPtr& request) : request_(request) {}

        void set(const std::string& key, const std::string& value, uint32_t max_age,
                 std::optional<std::string> top_level_domain) override {
            drogon::Cookie cookie{key, value};
            cookie.setPath("/");
            cookie.setMaxAge(static_cast<int>(max_age));
            if (top_level_domain.has_value() && !top_level_domain->empty()) {
                cookie.setDomain(std::move(*top_level_domain));
            }
            // Keyed by name: setting the same cookie twice yields one header.
            response_[key] = std::move(cookie);
        }

        std::optional<std::string> get(const std::string& key) override {
            // Check response cookies first, then fall back to request cookies
            if (const auto it = response_.find(key); it != response_.end()) return it->second.value();
            const auto& request_cookies = request_->getCookies();
            if (const auto it = request_cookies.find(key); it != request_cookies.end()) return it->second;
            return std::nullopt;
        }

        // Attach the SDK cookies to the response
        void apply(const drogon::HttpResponsePtr& response) const {
            for (const auto& [name, cookie] : response_) response->addCookie(cookie);
        }

    private:
        drogon::HttpRequestPtr request_;
        std::map<std::string, drogon::Cookie> response_;
    };

    void get_visitor_code(const drogon::HttpRequestPtr& request,
                          std::function<void(const drogon::HttpResponsePtr&)>&& callback) {
        DrogonCookieAccessor cookies{request};

        // Retrieve or generate a visitor code using the SDK
        std::string visitor_code = client.get_visitor_code(cookies);

        auto response = drogon::HttpResponse::newHttpResponse();
        response->setBody(visitor_code);
        // Attach any new/updated cookies to the response headers
        cookies.apply(response);
        callback(response);
    }
    ```
  </Tab>
</Tabs>

##### パラメーター

| 名前 | 型 | 説明 |
| - | - | - |
| `cookies` <Badge color="red" size="sm">必須</Badge> | `CookieAccessor&` | 訪問者 Cookie の読み取りと保存に使用される Cookie アクセサ。 |
| `default_visitor_code` <Badge color="green" size="sm">任意</Badge> | `std::optional<std::string>` | Cookie が存在しない場合に使用する訪問者コード。 |

##### 戻り値

| 型 | 説明 |
| - | - |
| `std::string` | SDK で使用される一意の訪問者コードを表す文字列。 |

##### 例外

| 型 | 説明 |
| - | - |
| `ErrorCode::Initialization` | SDK がまだ完全に初期化されていないことを示します。 |
| `ErrorCode::VisitorCodeInvalid` | 提供された訪問者コードが有効でないことを示す例外。空であるか、255 文字を超えています。 |
| `ErrorCode::InvalidSimVarCookieFormat` | `kameleoonSimulationFFData` Cookie に不正な形式の JSON が含まれており、シミュレートされたバリエーションを解析できなかったことを示します。 |

#### add\_data()

`add_data()` メソッドは、[ターゲティングデータ](#データ型)をストレージに追加し、他のメソッドがそのデータを使用して現在の訪問者をターゲットにするかどうかを判断できるようにします。

`add_data()` メソッドは値を返さず、単独では Kameleoon のバックエンドサーバーとやり取りしません。代わりに、SDK は宣言されたすべてのデータを [`flush()`](#flush) メソッドを使用した将来の送信のために保存します。このアプローチにより、データは通常、`flush()` によってトリガーされる単一のサーバー呼び出しにグループ化されるため、サーバー呼び出しの回数が削減されます。

[`track_conversion()`](#track_conversion) メソッドも、`flush()` と同様に、以前に関連付けられたデータをすべて送信します。実験ルールがトリガーされた場合、[`get_variation()`](#get_variation) および [`get_variations()`](#get_variations) メソッドについても同様です。

<Tip>
  ほとんどのデータ型では、各訪問者は関連付けられたデータのインスタンスを 1 つしか持てません。ただし、[`CustomData`](#customdata) は例外です。訪問者は、インデックスごとに 1 つの関連付けられた `CustomData` インスタンスを持つことができます。
</Tip>

`data` パラメータは `std::vector<Data>` です。ここで、`Data` はすべての[データ型](#データ型)の `std::variant` です。各データ型は暗黙的に `Data` に変換されるため、波括弧で囲んだデータオブジェクトのリストを渡すことができます。

```cpp theme={null}
using namespace kameleoon;

client.add_data(visitor_code, {Browser{.type = BrowserType::Chrome, .version = 123.0F}});

client.add_data(visitor_code, {
    PageView{.url = "https://example.com/pricing", .title = "Pricing", .referrers = {3}},
    UserAgent{"Mozilla/5.0"},
});

// Stores the data locally for targeting only, without sending it to Kameleoon
client.add_data(visitor_code, {PageView{.url = "https://example.com/checkout", .title = "Checkout"}}, false);
```

##### パラメーター

| 名前 | 型 | 説明 | デフォルト値 |
| - | - | - | - |
| `visitor_code` <Badge color="red" size="sm">必須</Badge> | `std::string` | 訪問者の一意の識別子。 | |
| `data` <Badge color="red" size="sm">必須</Badge> | `const std::vector<Data>&` | Kameleoon データ型のコレクション。 | |
| `track` <Badge color="green" size="sm">任意</Badge> | `bool` | 追加されたデータがトラッキングの対象かどうかを指定します。`false` に設定すると、SDK はデータをローカルに保存し、ターゲティング評価にのみ使用し、Kameleoon Data API には送信しません。 | `true` |

##### 例外

| 型 | 説明 |
| - | - |
| `ErrorCode::Initialization` | SDK がまだ完全に初期化されていないことを示します。 |
| `ErrorCode::VisitorCodeInvalid` | 提供された訪問者コードが有効でないことを示す例外。空であるか、255 文字を超えています。 |
| `ErrorCode::InvalidArgument` | 文字列が有効な UTF-8 でないか、enum 値が不明です。 |

#### flush()

* *📨 Kameleoon にトラッキングデータを送信します*

`flush()` メソッドは、訪問者に関連付けられたすべての Kameleoon データを集約し、サーバーにトラッキングリクエストを送信します。このリクエストには、[`add_data`](#add_data) メソッドで以前に追加され、他のトラッキングメカニズムを通じてまだ送信されていないデータが含まれます(詳細は参照先のメソッドを参照してください)。サーバー呼び出しは非同期で実行されるため、`flush()` 操作はノンブロッキングです。

このメソッドにより、特定の `visitor_code` にリンクされたデータがいつ送信されるかを制御できます。たとえば、`add_data()` が複数回呼び出された場合、呼び出しごとにリクエストを送信するのは非効率的です。代わりに、これらの更新をバッチ処理し、`flush()` を 1 回呼び出すことで、蓄積されたすべてのデータを単一のリクエストで送信できます。

`flush()` メソッドは、提供された `visitor_code` を一意の訪問者識別子として使用します。

<Tip>
  * `flush()`: 構成されたトラッキング間隔に従ってフラッシュ操作をキューに入れます。
  * `flush_instant()`: 間隔を待たずに、トラッキングデータをただちに送信します。
</Tip>

```cpp theme={null}
// Queues a flush operation for the given visitor_code.
// Data will be sent according to the configured tracking interval (non-blocking).
client.flush(visitor_code);

// Immediately sends all pending tracking data for the given visitor_code
// and blocks until the request completes.
client.flush_instant(visitor_code);

// Immediately sends all pending tracking data without blocking.
client.flush_instant_async(visitor_code, [](std::exception_ptr error) {
    // The immediate tracking operation completed.
});

// C++20 coroutines
co_await client.co_flush_instant(visitor_code);
```

##### パラメーター

| 名前 | 型 | 説明 |
| - | - | - |
| `visitor_code` <Badge color="red" size="sm">必須</Badge> | `std::string` | 訪問者の一意の識別子。 |

##### 例外

| 型 | 説明 |
| - | - |
| `ErrorCode::Initialization` | SDK がまだ完全に初期化されていないことを示します。 |
| `ErrorCode::VisitorCodeInvalid` | 提供された訪問者コードが有効でないことを示す例外。空であるか、255 文字を超えています。 |

#### get\_remote\_data()

`get_remote_data()` メソッドを使用すると、指定された `key` に対して Kameleoon サーバーに保存されているリモートデータを取得できます。ほとんどの構成では、このデータは Kameleoon Data API を通じて書き込まれ、追加のアプリコンテキストが必要になったときに C++ サービスから後で取得できます。

このメソッドは、構造化された情報を Kameleoon のリモートインフラストラクチャに保持し、別個の取得メカニズムを維持することなくバックエンドから再利用したい場合に便利です。

```cpp theme={null}
// Blocking
std::string data = client.get_remote_data("test-key");

// Completion: the value is only meaningful when `error` is null
client.get_remote_data_async("test-key", [](std::exception_ptr error, std::string data) {
    if (!error) {
        // Use `data`.
    }
});

// C++20 coroutines
std::string data = co_await client.co_get_remote_data("test-key");
```

##### パラメーター

| 名前 | 型 | 説明 |
| - | - | - |
| `key` <Badge color="red" size="sm">必須</Badge> | `std::string` | 取得したいリモートデータに関連付けられたキー。 |

##### 戻り値

| 型 | 説明 |
| - | - |
| `std::string` | 指定された `key` に関連付けられたペイロード。ほとんどの場合、ペイロードは文字列としてシリアル化された JSON です。ペイロードはバイト文字列であり、任意のバイトを含む可能性があります。 |

##### 例外

| 型 | 説明 |
| - | - |
| `ErrorCode::Initialization` | SDK がまだ完全に初期化されていないことを示します。 |
| `ErrorCode::Network` | リモートデータリクエストが失敗した場合、またはサーバーが成功以外のステータスコードで応答した場合にスローされます。 |

#### get\_remote\_visitor\_data()

`get_remote_visitor_data()` は、提供された `visitor_code` の Kameleoon 訪問データを取得します。このメソッドはデータをローカルの訪問者ストレージに追加し、他の SDK メソッドがターゲティングの判断に使用できるようにします。

このメソッドを使用して取得したデータは、次のような場合に特に役立ちます:

* 他のデバイスから収集したデータを使用する。
* 過去の訪問で以前に表示されたページなど、訪問者の履歴にアクセスする。
* datalayer 変数やフロントエンドの目標コンバージョンなど、クライアント側でのみ利用可能なデータを使用する。

可能なユースケースをより深く理解するには、[こちらの記事](/ja/developer-docs/feature-experimentation/targeting-and-segmentation/native-segmentation)をお読みください。

<Warning>
  デフォルトでは、`get_remote_visitor_data()` は `scope=Visitor` の最新の保存済みカスタムデータを自動的に取得し、[`add_data()`](#add_data) を呼び出すことなく訪問者にアタッチします。これは、[複数のデバイス間でのカスタムデータの同期](/ja/developer-docs/cross-device-experimentation/)に特に役立ちます。
</Warning>

```cpp theme={null}
using namespace kameleoon;

// Fetch remote visitor data without any filter
// This will return all available data for the given visitor
client.get_remote_visitor_data(visitor_code);

// Create a filter to limit the returned data
RemoteVisitorDataFilter filter{
    .previous_visit_amount = 5,  // Include data from the last 5 visits
    .page_views = true,          // Include page view history
    .conversions = true,         // Include conversion events (e.g., goals, transactions)
};

// Fetch remote visitor data using the specified filter
// This will return only the data matching the filter criteria
client.get_remote_visitor_data(visitor_code, filter);

// Non-blocking form
client.get_remote_visitor_data_async(visitor_code, filter, [](std::exception_ptr error) {
    // The data is available locally when `error` is null.
});

// C++20 coroutines
co_await client.co_get_remote_visitor_data(visitor_code, filter);
```

##### パラメーター

| 名前 | 型 | 説明 | デフォルト |
| - | - | - | - |
| `visitor_code` <Badge color="red" size="sm">必須</Badge> | `std::string` | データを取得する対象の訪問者コード。 | |
| `filter` <Badge color="green" size="sm">任意</Badge> | `RemoteVisitorDataFilter` | 取得するリモート訪問者データを記述するフィルター。 | `RemoteVisitorDataFilter{}` |

##### 例外

| 型 | 説明 |
| - | - |
| `ErrorCode::Initialization` | SDK がまだ完全に初期化されていないことを示します。 |
| `ErrorCode::VisitorCodeInvalid` | 提供された訪問者コードが有効でないことを示す例外。空であるか、255 文字を超えています。 |
| `ErrorCode::Network` | リモート訪問者データリクエストが失敗した場合、解析できない場合、またはサーバーが成功以外のステータスコードで応答した場合にスローされます。 |

##### get\_remote\_visitor\_data() でのパラメータの使用

`get_remote_visitor_data()` メソッドを使用すると、訪問者に対してどのデータを取得するかを制御できます。同じフィルタリングアプローチが、目標、実験、バリエーション、およびその他の訪問者データ全体で機能します。

たとえば、直近 5 回の訪問中に目標でコンバージョンしたユーザーをターゲットにしたい場合、`previous_visit_amount` を `5` に、`conversions` を `true` に設定できます。

この例で示した柔軟性は、目標データに限定されません。フィルターを使用して、さまざまな訪問者の行動を取得し、C++ アプリのターゲティングおよびレポートロジックで利用できるようにすることができます。

##### `RemoteVisitorDataFilter` フィールド

| 名前 | 型 | 説明 | デフォルト |
| - | - | - | - |
| `previous_visit_amount` | `uint32_t` | データを取得する過去の訪問数。 | `1` |
| `current_visit` | `bool` | `true` の場合、現在の訪問データが取得されます。 | `true` |
| `custom_data` | `bool` | `true` の場合、カスタムデータが取得されます。 | `true` |
| `visitor_code` | `bool` | `true` の場合、最新の訪問者コードが再利用されます。 | `true` |
| `page_views` | `bool` | `true` の場合、ページビューデータが取得されます。 | `false` |
| `geolocation` | `bool` | `true` の場合、位置情報データが取得されます。 | `false` |
| `device` | `bool` | `true` の場合、デバイスデータが取得されます。 | `false` |
| `browser` | `bool` | `true` の場合、ブラウザーデータが取得されます。 | `false` |
| `operating_system` | `bool` | `true` の場合、オペレーティングシステムデータが取得されます。 | `false` |
| `conversions` | `bool` | `true` の場合、コンバージョンデータが取得されます。 | `false` |
| `experiments` | `bool` | `true` の場合、実験データが取得されます。 | `false` |
| `kcs` | `bool` | `true` の場合、Kameleoon Conversion Score データが取得されます。 | `false` |
| `personalizations` | `bool` | `true` の場合、パーソナライゼーションデータが取得されます。 | `false` |
| `cbs` | `bool` | true の場合、SDK は Contextual Bandit スコアデータを取得します。 | `false` |

#### get\_visitor\_warehouse\_audience()

このメソッドは、指定された `visitor_code` と、オプションで `warehouse_key` を使用して、ウェアハウス統合内で訪問者に関連付けられたオーディエンスデータを取得します。`warehouse_key` は通常、内部のユーザー ID です。`custom_data_index` パラメータは、Kameleoon が訪問者のターゲティングに使用する Kameleoon カスタムデータに対応します。

呼び出しが成功すると、SDK は返されたオーディエンスリストを [`CustomData`](#customdata) に変換し、訪問者にローカルで追加して、ターゲティングの目的で利用できるようにします。背景の詳細については、[ウェアハウスターゲティングのドキュメント](/ja/user-manual/integrations/data-warehouses/bigquery/use-bigquery-as-a-source-audience-targeting)を参照してください。

```cpp theme={null}
// Fetch audience data for a visitor using only the visitor_code.
client.get_visitor_warehouse_audience(visitor_code, 98);

// Fetch audience data for a visitor using both visitor_code and warehouse_key.
// Useful when your warehouse uses a different identifier than visitor_code.
client.get_visitor_warehouse_audience(visitor_code, 98, "internal-user-id");

// Non-blocking form
client.get_visitor_warehouse_audience_async(visitor_code, 98, "internal-user-id", [](std::exception_ptr error) {
    // The audience data is available locally when `error` is null.
});

// C++20 coroutines
co_await client.co_get_visitor_warehouse_audience(visitor_code, 98, "internal-user-id");
```

##### パラメーター

| 名前 | 型 | 説明 | デフォルト |
| - | - | - | - |
| `visitor_code` <Badge color="red" size="sm">必須</Badge> | `std::string` | ウェアハウスオーディエンスを取得する対象の訪問者。 | |
| `custom_data_index` <Badge color="red" size="sm">必須</Badge> | `uint32_t` | ウェアハウスオーディエンスターゲティング用に Kameleoon で構成されたカスタムデータのインデックス。 | |
| `warehouse_key` <Badge color="green" size="sm">任意</Badge> | `std::optional<std::string>` | 外部ウェアハウスキー。通常は内部のユーザー ID です。省略した場合、SDK は `visitor_code` を使用します。 | `std::nullopt` |

##### 例外

| 型 | 説明 |
| - | - |
| `ErrorCode::Initialization` | SDK がまだ完全に初期化されていないことを示します。 |
| `ErrorCode::VisitorCodeInvalid` | 提供された訪問者コードが有効でないことを示す例外。空であるか、255 文字を超えています。 |
| `ErrorCode::Network` | ウェアハウスオーディエンスリクエストが失敗した場合、解析できない場合、またはサーバーが成功以外のステータスコードで応答した場合にスローされます。 |

#### set\_legal\_consent()

訪問者が個人データの使用に法的同意を与えたかどうかを指定するには、このメソッドを使用する必要があります。`consent` を `false` に設定すると、トラッキングリクエストに含めることができるデータの種類が制限されます。これにより、訪問者データを責任を持って管理しながら、法的および規制上の要件を遵守できます。詳細については、[同意管理ポリシー](/ja/user-manual/project-management/consent-management-policy)を参照してください。

`CookieAccessor` を渡すと、SDK は同意ステータスに従って訪問者の Cookie も更新します。

```cpp theme={null}
// Set consent and update cookies
client.set_legal_consent(visitor_code, true, &cookies);

// Set consent without updating cookies
client.set_legal_consent(visitor_code, true);
```

##### パラメーター

| 名前 | 型 | 説明 | デフォルト |
| - | - | - | - |
| `visitor_code` <Badge color="red" size="sm">必須</Badge> | `std::string` | ユーザーの一意の識別子。 | |
| `consent` <Badge color="red" size="sm">必須</Badge> | `bool` | `true` は訪問者が法的同意を与えたことを示し、`false` は訪問者が法的同意を一度も提供していないか、撤回したことを示します。 | |
| `cookies` <Badge color="green" size="sm">任意</Badge> | `CookieAccessor*` | Cookie の更新に使用されるオプションの Cookie アクセサ。 | `nullptr` |

##### 例外

| 型 | 説明 |
| - | - |
| `ErrorCode::Initialization` | SDK がまだ完全に初期化されていないことを示します。 |
| `ErrorCode::VisitorCodeInvalid` | 提供された訪問者コードが有効でないことを示す例外。空であるか、255 文字を超えています。 |

##### 同意撤回時の動作

`consent=false` で `set_legal_consent()` を呼び出した場合、SDK は `kameleoonVisitorCode` Cookie を削除しません。代わりに、Cookie の有効期限の延長を停止し、Cookie が自然に期限切れになるまで保持されるようにします。

コンプライアンス要件により、オプトアウト時に Cookie ファイルの即時削除が求められる場合は、フレームワークのネイティブな Cookie 管理メソッドを使用して手動で削除する必要があります。SDK はファイルを自動的に削除しません。

### 目標とサードパーティ分析

#### track\_conversion()

* 📨 *Kameleoon にトラッキングデータを送信します*

このメソッドを使用して、特定の[目標](/ja/user-manual/assets/goals/create-a-goal)とユーザーのコンバージョンをトラッキングします。このメソッドには `visitor_code` と `goal_id` が必要です。さらに、このメソッドはオプションの `revenue`、`negative`、`metadata` 引数も受け取ります。`visitor_code` は通常、実験をトリガーしたときに使用したものと同一です。

<Tip>
  SDK はサーバー呼び出しを非同期で行うため、このメソッドはノンブロッキングです。
</Tip>

```cpp theme={null}
using namespace kameleoon;

// Track a goal
client.track_conversion(visitor_code, goal_id);

// Track a goal with revenue
client.track_conversion(visitor_code, goal_id, TrackConversionOptions{.revenue = 100.0F});

// Track a goal with negative revenue
client.track_conversion(
    visitor_code, goal_id, TrackConversionOptions{.revenue = 100.0F, .negative = true});

// Track a goal with custom metadata
client.track_conversion(
    visitor_code, goal_id, TrackConversionOptions{.metadata = {CustomData(4, {"true"})}});
```

##### パラメーター

| 名前 | 型 | 説明 | デフォルト |
| - | - | - | - |
| `visitor_code` <Badge color="red" size="sm">必須</Badge> | `std::string` | 訪問者の一意の識別子。 | |
| `goal_id` <Badge color="red" size="sm">必須</Badge> | `uint32_t` | 目標の ID。 | |
| `revenue` <Badge color="green" size="sm">任意</Badge> | `float` | コンバージョンの収益。 | `0` |
| `negative` <Badge color="green" size="sm">任意</Badge> | `bool` | 収益が正か負かを定義します。 | `false` |
| `metadata` <Badge color="green" size="sm">任意</Badge> | `std::vector<CustomData>` | コンバージョンのメタデータ。[事前に Kameleoon アプリで定義する必要があります](/ja/user-manual/assets/goals/create-a-goal#メタデータ)。 | `{}` |

<Note>
  オプションの `revenue`、`negative`、`metadata` パラメータは、`TrackConversionOptions` 構造体のフィールドとして渡されます。
</Note>

<Note>
  メタデータの値には、[生データエクスポート](/ja/user-manual/experiment-analytics/analyze-results/results-page/results-page-actions#エクスポート)と[結果ページ](/ja/user-manual/experiment-analytics/analyze-results/data-and-metrics/goal-metadata)からアクセスできます。

  `metadata` パラメータを提供すると、Kameleoon は、以前に [`add_data()`](#add_data) メソッドを使用して収集したものの代わりに、現在のコンバージョンに対してこれらの指定された値を使用します。パラメータを省略すると、Kameleoon は、コンバージョンの前かつ同じ訪問内でそれらの [`CustomData`](#customdata) に対して最後にトラッキングされた値を使用します。

  Kameleoon は、`track_conversion()` メソッドにパラメータとして明示的に渡されたメタデータ値のみを考慮します。

  次の例では、Kameleoon はパラメータとして明示的に提供されたカスタムデータ値(ここでは、値が「Amex Credit Card」のインデックス 5)のみにコンバージョンを関連付けます。

  ```cpp theme={null}
  client.add_data(visitor_code, {
      CustomData(5, {"Credit Card"}),
      CustomData(9, {"Express Delivery"}),
  });

  client.track_conversion(
      visitor_code, goal_id, TrackConversionOptions{.metadata = {CustomData(5, {"Amex Credit Card"})}});
  ```
</Note>

##### 例外

| 型 | 説明 |
| - | - |
| `ErrorCode::Initialization` | SDK がまだ完全に初期化されていないことを示します。 |
| `ErrorCode::VisitorCodeInvalid` | 提供された訪問者コードが有効でないことを示す例外。空であるか、255 文字を超えています。 |

#### get\_engine\_tracking\_code()

Kameleoon は、Mixpanel、Google Analytics 4、Segment など、いくつかの分析ソリューションと統合されています。サーバー側の実験を正しくトラッキングするには、訪問者が実験をトリガーした後に `get_engine_tracking_code()` メソッドを呼び出します。SDK は、訪問者が直前の 5 秒間にトリガーした実験の JavaScript キューコマンドを返します。このコードをページに挿入すると、Engine.js がコマンドを処理し、アクティブな分析統合を通じてエクスポージャーイベントを送信します。

このメソッドの実装の詳細については、[ハイブリッド実験](/ja/developer-docs/feature-experimentation/get-started/hybrid-experimentation)を参照してください。

```cpp theme={null}
std::string tracking_code = client.get_engine_tracking_code(visitor_code);
```

<Note>
  * この機能を使用するには、C++ SDK と Kameleoon [Engine.js](/ja/developer-docs/web-experimentation/implementation-and-deployment/standard-implementation) の両方を実装してください。このフローは Engine.js をトラッキングのみに使用するため、非同期タグは閉じタグ `</body>` の前にインストールできます。
  * Kameleoon でのみ実験をトラッキングし、サードパーティの分析ツールにエクスポージャーイベントを送信する必要がない場合は、[JavaScript / TypeScript SDK](/ja/developer-docs/sdks/web-sdks/js-sdk) を使用してください。このオプションは、[サーバーレスエッジコンピューティングプラットフォーム](/ja/developer-docs/feature-experimentation/implementation-and-deployment/serverless-edge-compute-starter-kits)に適しています。対応する実験の割り当てを `window.kameleoonQueue` に追加している限り、JavaScript / TypeScript SDK は [`getVisitorCode`](/ja/developer-docs/sdks/web-sdks/js-sdk#getvisitorcode) を呼び出すと自動的にバリエーションをトラッキングします。
  * 返されたトラッキングコードは、HTML の `<script>` タグに直接挿入できます。

  ```html theme={null}
  <html lang="en">
    <body>
      <script>
        const engineTrackingCode = `
          window.kameleoonQueue = window.kameleoonQueue || [];
          window.kameleoonQueue.push(['Experiments.assignVariation', 123456, 7890, true]);
          window.kameleoonQueue.push(['Experiments.trigger', 123456, true]);
          window.kameleoonQueue.push(['Experiments.assignVariation', 234567, 8901, true]);
          window.kameleoonQueue.push(['Experiments.trigger', 234567, true]);
        `;
        const script = document.createElement('script');

        script.textContent = engineTrackingCode;
        document.body.appendChild(script);
      </script>

    </body>
  </html>
  ```

  この例では、`123456` と `234567` は実験 ID、`7890` と `8901` はバリエーション ID です。実装では、SDK が返されるトラッキングコード内にこれらの値を生成します。
</Note>

##### パラメーター

| 名前 | 型 | 説明 |
| - | - | - |
| `visitor_code` <Badge color="red" size="sm">必須</Badge> | `std::string` | 訪問者の一意の識別子。 |

##### 戻り値

| 型 | 説明 |
| - | - |
| `std::string` | ページに挿入する JavaScript コード。 |

##### 例外

| 型 | 説明 |
| - | - |
| `ErrorCode::Initialization` | SDK がまだ完全に初期化されていないことを示します。 |
| `ErrorCode::VisitorCodeInvalid` | 提供された訪問者コードが有効でないことを示す例外。空であるか、255 文字を超えています。 |

### イベント

#### set\_event\_handler()

このメソッドを使用して、SDK イベントのハンドラーを登録します。選択したイベントが発生すると、SDK はハンドラーを呼び出します。クライアントは、イベントタイプごとに最大 1 つのハンドラーを保持します。同じイベントタイプに新しいハンドラーを登録すると、以前のハンドラーが置き換えられます。

使用する `EventHandler` コンストラクタ(`EventHandler::datafile_update()` または `EventHandler::http_request()`)がイベントタイプを選択するため、ハンドラーとそれが受け取るイベントが同期しなくなることはありません。空の `std::function`(`{}`)を渡すと、選択したイベントタイプの現在のハンドラーが削除されます。

<Tabs>
  <Tab title="datafile_update">
    ```cpp theme={null}
    #include "kameleoon/events.hpp"

    using namespace kameleoon;

    client.set_event_handler(EventHandler::datafile_update([](const DataFileUpdateEvent& event) {
        DataFileUpdateSource source = event.source; // DataFileUpdateSource::Polling or DataFileUpdateSource::Streaming
        uint64_t date_modified = event.date_modified; // Data file modification date in milliseconds.

        // React to the data file update.
    }));

    // Clear the handler.
    client.set_event_handler(EventHandler::datafile_update({}));
    ```

    <Tip>
      `DataFileUpdateEvent` には、SDK データファイルの更新に関する情報が含まれます。

      | 名前 | 型 | 説明 |
      | - | - | - |
      | `source` | `DataFileUpdateSource` | 更新ソース。[`DataFileUpdateSource::Polling`](/ja/developer-docs/feature-experimentation/technical-reference/technical-considerations#ポーリング（デフォルト）) はスケジュールされたデータファイルの更新を示し、[`DataFileUpdateSource::Streaming`](/ja/developer-docs/feature-experimentation/technical-reference/technical-considerations#ストリーミング（プレミアムオプション）) はストリーミングモードで受信したリアルタイム更新を示します。 |
      | `date_modified` | `uint64_t` | 更新されたデータファイルの変更日(ミリ秒単位)。 |
    </Tip>
  </Tab>

  <Tab title="http_request">
    ```cpp theme={null}
    #include "kameleoon/events.hpp"

    #include <variant>

    using namespace kameleoon;

    client.set_event_handler(EventHandler::http_request([](const HttpRequestEvent& event) {
        if (const auto* succeeded = std::get_if<HttpRequestSucceeded>(&event)) {
            // The SDK request completed successfully.
            RequestType request_type = succeeded->request_type;
            uint16_t http_status = succeeded->http_status;
            std::chrono::milliseconds duration = succeeded->duration;
        } else if (const auto* failed = std::get_if<HttpRequestFailed>(&event)) {
            // The SDK request failed.
            HttpRequestFailureReason reason = failed->failure.reason; // HttpStatus, Error, or Cancelled
            std::optional<uint16_t> http_status = failed->failure.http_status;
            std::optional<std::string> cause = failed->failure.cause;
        }
    }));

    // Clear the handler.
    client.set_event_handler(EventHandler::http_request({}));
    ```

    <Tip>
      `HttpRequestEvent` は `std::variant<HttpRequestSucceeded, HttpRequestFailed>` です。SDK は、再試行を含む実際の HTTP リクエスト試行ごとに 1 回イベントを報告します。成功したリクエストと失敗したリクエストを区別するには、`std::get_if` または `std::visit` を使用してください。

      | 型 | 説明 |
      | - | - |
      | `HttpRequestSucceeded` | 正常に完了した SDK の HTTP リクエストを記述します。常に `http_status` を持ちます。 |
      | `HttpRequestFailed` | HTTP ステータス、エラー、またはキャンセルが原因で失敗した SDK の HTTP リクエストを記述します。常に `failure` を持ちます。 |

      <Accordion title="イベントデータフィールドと失敗の詳細">
        ##### イベントデータフィールド

        | 名前 | 型 | 説明 |
        | - | - | - |
        | `request_type` | `RequestType` | SDK のリクエストタイプ。可能な値は `RequestType::DataFile`、`RequestType::Tracking`、`RequestType::RemoteVisitorData`、`RequestType::RemoteData`、`RequestType::AccessToken` です。 |
        | `http_status` | `uint16_t` | リクエストによって返された HTTP ステータスコード。`HttpRequestSucceeded` にのみ存在します。 |
        | `failure` | `HttpRequestFailure` | リクエストが失敗した理由の詳細。`HttpRequestFailed` にのみ存在します。 |
        | `duration` | `std::chrono::milliseconds` | リクエストの所要時間。 |

        ##### HttpRequestFailure

        `HttpRequestFailure` には、失敗した SDK の HTTP リクエストに関する詳細が含まれます。

        | 名前 | 型 | 説明 |
        | - | - | - |
        | `reason` | `HttpRequestFailureReason` | 失敗の理由。可能な値は `HttpRequestFailureReason::HttpStatus`、`HttpRequestFailureReason::Error`、`HttpRequestFailureReason::Cancelled` です。 |
        | `http_status` | `std::optional<uint16_t>` | 不成功の HTTP レスポンスが原因の失敗に対する HTTP ステータスコード。例外やキャンセルによる失敗の場合、この値は `std::nullopt` です。 |
        | `cause` | `std::optional<std::string>` | リクエストの失敗の原因となった例外(エラー)。HTTP ステータスまたはキャンセルが原因でリクエストが失敗した場合、この値は `std::nullopt` です。 |
      </Accordion>
    </Tip>
  </Tab>
</Tabs>

<Note>
  ハンドラーは SDK の単一のワーカースレッド上で同期的に呼び出されるため、ブロックしてはいけません。ハンドラー内で費やされた時間は、データファイルのポーリングとトラッキングのフラッシュを遅延させます。ハンドラーはスレッドセーフであり、例外をスローしてはいけません。ハンドラーから漏れた例外はキャッチされて破棄され、SDK の動作に影響を与えることはありません。ハンドラーからブロッキングする SDK 操作を呼び出さないでください。代わりに `*_async` 形式を使用し、アプリケーションスレッドで作業を完了させてください。

  すでに進行中の呼び出しは、ハンドラーをクリアした後やクライアントを破棄した後に完了する場合があり、ハンドラー(およびそのキャプチャ)は、使用されなくなった時点で SDK スレッド上で破棄されます。キャプチャされたオブジェクトは、それに応じて存続させ、スレッドセーフに保ってください。ハンドラーは自分自身をクリアまたは置き換えることができます。

  同じサイトコードと環境に対して作成されたすべての `KameleoonClient` インスタンスは、イベントタイプごとに 1 つのハンドラーを共有します。最後に設定されたハンドラーが優先され、それらのインスタンスのいずれかを破棄するとクリアされます。サイトコードと環境ごとに単一のクライアントインスタンスを保持してください。
</Note>

##### パラメーター

| 名前 | 型 | 説明 |
| - | - | - |
| `handler` <Badge color="red" size="sm">必須</Badge> | `EventHandler` | 登録するハンドラー。`DataFileUpdateHandler`(`std::function<void(const DataFileUpdateEvent&)>`)から `EventHandler::datafile_update()` で構築するか、`HttpRequestHandler`(`std::function<void(const HttpRequestEvent&)>`)から `EventHandler::http_request()` で構築します。そのイベントタイプの現在のハンドラーを削除するには、空の `std::function` を渡してください。 |

### データ型

このセクションでは、SDK が `kameleoon` 名前空間(`kameleoon/data/*.hpp`)で宣言する C++ データ型を一覧します。これらはすべて、[`add_data()`](#add_data) に渡すプレーンな構造体です。

#### ApplicationVersion

`ApplicationVersion` は、アプリケーションのセマンティックバージョン番号を表します。

<Tip>
  **訪問者**は 1 つの `ApplicationVersion` しか持てません。2 つ目のインスタンスを追加すると、最初のものが上書きされます。
</Tip>

| 名前 | 型 | 説明 |
| - | - | - |
| `value` <Badge color="red" size="sm">必須</Badge> | `std::string` | アプリのバージョン。このフィールドはセマンティックバージョニングに従う必要があります。受け入れられる形式は `major`、`major.minor`、または `major.minor.patch` です。 |

```cpp theme={null}
using namespace kameleoon;

// major
client.add_data(visitor_code, {ApplicationVersion{"10"}});
// major.minor
client.add_data(visitor_code, {ApplicationVersion{"10.20"}});
// major.minor.patch
client.add_data(visitor_code, {ApplicationVersion{"10.20.30"}});
```

#### Browser

ここに保存された `Browser` データセットを使用して、それに関連付けられた任意の値で実験およびパーソナライゼーションのレポートをフィルタリングできます。

| 名前 | 型 | 説明 |
| - | - | - |
| `type` <Badge color="red" size="sm">必須</Badge> | `BrowserType` | ブラウザーのリスト: `BrowserType::Chrome`、`BrowserType::InternetExplorer`、`BrowserType::Firefox`、`BrowserType::Safari`、`BrowserType::Opera`、`BrowserType::Other`。 |
| `version` <Badge color="green" size="sm">任意</Badge> | `std::optional<float>` | ブラウザーのバージョン。浮動小数点数はブラウザーのメジャーバージョンとマイナーバージョンを表します |

```cpp theme={null}
using namespace kameleoon;

// Browser data with a version
client.add_data(visitor_code, {Browser{.type = BrowserType::Safari, .version = 26.4F}});
// Browser data without a version
client.add_data(visitor_code, {Browser{.type = BrowserType::Chrome}});
```

#### Conversion

ここに保存された `Conversion` データセットを使用して、それに関連付けられた任意の目標で実験およびパーソナライゼーションのレポートをフィルタリングできます。

<Tip>
  * 各訪問者は複数の `Conversion` オブジェクトを持つことができます。
  * `goal_id` は Kameleoon アプリで確認できます。
</Tip>

| 名前 | 型 | 説明 | デフォルト |
| - | - | - | - |
| `goal_id` <Badge color="red" size="sm">必須</Badge> | `uint32_t` | 目標の ID。 | |
| `revenue` <Badge color="green" size="sm">任意</Badge> | `float` | コンバージョンの収益 | `0` |
| `negative` <Badge color="green" size="sm">任意</Badge> | `bool` | 収益が正か負かを定義します。 | `false` |
| `metadata` <Badge color="green" size="sm">任意</Badge> | `std::vector<CustomData>` | コンバージョンのメタデータ。 | `{}` |

```cpp theme={null}
using namespace kameleoon;

// Add a simple conversion with ID 32
client.add_data(visitor_code, {Conversion{.goal_id = 32}});

// Add conversion with ID 33 including revenue and marked as negative
client.add_data(visitor_code, {Conversion{.goal_id = 33, .revenue = 10.0F, .negative = true}});

// Add conversion with ID 34 including revenue, negative flag, and custom metadata
client.add_data(visitor_code, {
    Conversion{
        .goal_id = 34,
        .revenue = 10.0F,
        .negative = true,
        .metadata = {
            CustomData(3, {"metadata1", "md2"}),
            CustomData(5, {"md3"}),
        },
    },
});
```

#### Cookie

`Cookie` には、訪問者のデバイスに保存されている Cookie に関する情報が含まれます。

| 名前 | 型 | 説明 |
| - | - | - |
| `cookies` | `std::unordered_map<std::string, std::string>` | Cookie のキーと値を含む文字列マップ。 |

<Tip>
  各訪問者は 1 つの `Cookie` しか持てません。2 つ目の `Cookie` を追加すると、最初のものが上書きされます。
</Tip>

```cpp theme={null}
using namespace kameleoon;

client.add_data(visitor_code, {Cookie{.cookies = {{"segment", "vip"}}}});
```

#### CustomData

`CustomData` を使用すると、あらゆる種類のデータを各訪問者に関連付けることができ、[セグメント](/ja/user-manual/assets/segments/create-a-segment/)のターゲティング条件の効果的なツールになります。さらに、実験レポートのフィルターやブレークダウンとしても使用できます。カスタムデータの詳細については、こちらの[記事](/ja/developer-docs/custom-data)を参照してください。

Kameleoon アプリまたは Data API でカスタムデータの型を定義し、SDK から使用します。

`CustomData` には 2 つのコンストラクタがあります。1 つはカスタムデータを `id`(インデックス)で識別し、もう 1 つは `name` で識別します。

| 名前 | 型 | 説明 | デフォルト |
| - | - | - | - |
| `id`/`name` <Badge color="red" size="sm">必須</Badge> | `uint32_t`/`std::string` | カスタムデータのインデックスまたは名前。データを識別するには、**`id` または `name` のいずれかを提供する必要があります**。 | |
| `values` <Badge color="red" size="sm">必須</Badge> | `std::vector<std::string>` | 保存するカスタムデータの値。 | |
| `overwrite` <Badge color="green" size="sm">任意</Badge> | `bool` | 値の保存方法とレポートでの表示方法を明示的に制御するフラグ。[詳細を見る](/ja/developer-docs/custom-data#デフォルトロジック（overwriteパラメータがfalseまたは省略された場合）) | `true` |

<Note>
  * 各訪問者は、一意の `id`(`name`)ごとに 1 つの `CustomData` しか持てません。同じ `id`(`name`)を持つ別の `CustomData` を追加すると、既存のものが置き換えられます。

  * カスタムデータの「インデックス」は、[カスタムデータダッシュボード](/ja/user-manual/assets/custom-data/manage-custom-data)の「INDEX」列で確認できます。

  * プライバシー上の理由から、SDK が選択したインデックスのデータを Kameleoon サーバーに送信しないようにするには、カスタムデータの作成時に **Use this data only locally for targeting purposes** オプションを有効にしてください。

  * SDK インスタンスが初期化されていない、または名前が登録されていないときに、名前で作成された `CustomData` インスタンスを追加すると、データは無視されます。
</Note>

```cpp theme={null}
using namespace kameleoon;

client.add_data(visitor_code, {CustomData(1, {"value"})});

// With several values
client.add_data(visitor_code, {CustomData(1, {"value1", "value2"})});

// To set the `overwrite` flag to false
client.add_data(visitor_code, {CustomData(1, {"value"}, false)});

// To use a name instead of the index
client.add_data(visitor_code, {CustomData("my-custom-data", {"value"})});

// To use a name instead of the index and set the `overwrite` flag to false
client.add_data(visitor_code, {CustomData("my-custom-data", {"value"}, false)});
```

#### Device

デバイスデータを使用して、関連付けられた任意の値で実験およびパーソナライゼーションのレポートをフィルタリングできます。

| 名前 | 型 | 説明 |
| - | - | - |
| `type` | `DeviceType` | デバイスタイプ。可能な値は `DeviceType::Phone`、`DeviceType::Tablet`、`DeviceType::Desktop` です。 |

```cpp theme={null}
using namespace kameleoon;

client.add_data(visitor_code, {Device{DeviceType::Desktop}});
```

#### Geolocation

`Geolocation` には、訪問者の位置情報の詳細が含まれます。

| 名前 | 型 | 説明 |
| - | - | - |
| `country` <Badge color="red" size="sm">必須</Badge> | `std::string` | 訪問者の国。 |
| `region` <Badge color="green" size="sm">任意</Badge> | <nobr>`std::optional<std::string>`</nobr> | 訪問者の地域。 |
| `city` <Badge color="green" size="sm">任意</Badge> | <nobr>`std::optional<std::string>`</nobr> | 訪問者の都市。 |
| `postal_code` <Badge color="green" size="sm">任意</Badge> | <nobr>`std::optional<std::string>`</nobr> | 訪問者の郵便番号。 |
| `latitude` <Badge color="green" size="sm">任意</Badge> | `std::optional<float>` | 訪問者の位置を表す緯度座標。座標の数値は十進度を表します。 |
| `longitude` <Badge color="green" size="sm">任意</Badge> | `std::optional<float>` | 訪問者の位置を表す経度座標。座標の数値は十進度を表します。 |

<Tip>
  * 各訪問者は 1 つの `Geolocation` しか持てません。2 つ目の `Geolocation` を追加すると、最初のものが上書きされます。
</Tip>

```cpp theme={null}
using namespace kameleoon;

client.add_data(visitor_code, {
    Geolocation{
        .country = "France",
        .region = "Ile-de-France",
        .city = "Paris",
        .postal_code = "75009",
        .latitude = 48.8720171F,
        .longitude = 2.3338352F,
    },
});
```

#### OperatingSystem

`OperatingSystem` には、訪問者のデバイスのオペレーティングシステムに関する情報が含まれます。

| 名前 | 型 | 説明 |
| - | - | - |
| `type` | `OperatingSystemType` | オペレーティングシステムのファミリー。可能な値は `OperatingSystemType::Windows`、`OperatingSystemType::Mac`、`OperatingSystemType::IOS`、`OperatingSystemType::Linux`、`OperatingSystemType::Android`、`OperatingSystemType::WindowsPhone` です。 |

<Tip>
  各訪問者は 1 つの `OperatingSystem` しか持てません。2 つ目の `OperatingSystem` を追加すると、最初のものが上書きされます。
</Tip>

```cpp theme={null}
using namespace kameleoon;

client.add_data(visitor_code, {OperatingSystem{OperatingSystemType::Windows}});
```

#### PageView

ページビューイベントを保存します。

| 名前 | 型 | 説明 | デフォルト |
| - | - | - | - |
| `url` | `std::string` | 表示されたページの URL。 | |
| `title` | `std::optional<std::string>` | 表示されたページのタイトル。 | `std::nullopt` |
| `referrers` | `std::vector<int32_t>` | 以前に表示されたページのリファラーインデックス。 | `{}` |

<Note>
  リファラーインデックスは、Kameleoon アプリの[獲得チャネル構成](/ja/user-manual/assets/advanced-targeting-tools/create-an-acquisition-channel)ページで確認できます。注意: インデックスは `0` から始まるため、最初に作成した獲得チャネルの ID は `1` ではなく `0` です。
</Note>

```cpp theme={null}
using namespace kameleoon;

// Full initialization with url, title, and referrers
client.add_data(visitor_code, {PageView{.url = "https://example.com", .title = "Homepage", .referrers = {3}}});

// Minimal initialization, only requires a URL
client.add_data(visitor_code, {PageView{.url = "https://example.com"}});
```

#### UniqueIdentifier

訪問者に `UniqueIdentifier` を追加しない場合、`visitor_code` が一意の訪問者識別子として使用されます。これは[クロスデバイス実験](/ja/developer-docs/cross-device-experimentation/)に役立ちます。`UniqueIdentifier{true}` を追加すると、SDK はフラッシュされたデータを、指定された識別子に関連付けられた訪問者にリンクします。

これは、訪問者に最初に割り当てられた匿名の `visitor_code` にはアクセスできないが、セッションマージを通じてその訪問者に接続された内部識別子にはアクセスできる状況で役立ちます。

| 名前 | 型 | 説明 |
| - | - | - |
| `value` | `bool` | 現在の `visitor_code` を一意の識別子として扱うかどうか。 |

```cpp theme={null}
using namespace kameleoon;

client.add_data(visitor_code, {UniqueIdentifier{true}});
```

#### UserAgent

サーバー側の実験は、クライアント側の実験よりもボットトラフィックの影響を受けやすくなります。Kameleoon は、IAB/ABC International Spiders and Bots List を使用して既知のボットやスパイダーを認識し、さらに `UserAgent` フィールドを使用して、コンバージョン指標を歪める可能性のあるその他の不要なトラフィックを除外します。詳細については、[ボットフィルタリング](/ja/user-manual/experiment-analytics/troubleshooting/data-discrepancies#how-does-kameleoon-filter-bot-traffic-from-my-results)に関するヘルプ記事を参照してください。

内部ボットを使用している場合は、user-agent 値 `curl/8.0` を送信して分析から除外してください。

| 名前 | 型 | 説明 |
| - | - | - |
| `value` | `std::string` | トラッキングリクエストと共に送信される User-Agent 値。 |

```cpp theme={null}
using namespace kameleoon;

client.add_data(visitor_code, {UserAgent{"Mozilla/5.0"}});
```

### 返される型

#### DataFile

`DataFile` には、SDK 構成の詳細が含まれます。

クライアントが必要とする場合、追加情報で拡張できます。詳細が必要な場合は、カスタマーサクセスマネージャーにお問い合わせください。

| 名前 | 型 | 説明 |
| - | - | - |
| `feature_flags` | `std::unordered_map<std::string, FeatureFlag>` | フィーチャーフラグのキーをキーとする [`FeatureFlag`](#featureflag) オブジェクトのマップ。 |
| `date_modified` | `uint64_t` | `DataFile` が最後に変更された日時を示すタイムスタンプ(ミリ秒単位)。 |

```cpp theme={null}
// Retrieves the map of feature flags from the DataFile.
// The map is keyed by feature flag identifiers, with each value being a FeatureFlag object.
const std::unordered_map<std::string, FeatureFlag>& feature_flags = datafile.feature_flags;

// Retrieves the last modification timestamp of the DataFile.
// The value is a uint64_t representing milliseconds since the Unix epoch.
uint64_t date_modified = datafile.date_modified;
```

#### FeatureFlag

`FeatureFlag` は、フィーチャーフラグ自体を定義するプロパティのセット(たとえば、その [`Variations`](#variation)、[`Rules`](#rule)、環境ステータス、およびその他の関連する詳細)を表します。

クライアントが必要とする場合、追加情報で拡張できます。詳細が必要な場合は、カスタマーサクセスマネージャーにお問い合わせください。

| 名前 | 型 | 説明 |
| - | - | - |
| `environment_enabled` | `bool` | フィーチャーフラグが現在の環境で有効かどうかを示します。 |
| `default_variation_key` | `std::string` | フィーチャーフラグに関連付けられたデフォルトバリエーションのキー。 |
| `variations` | `std::unordered_map<std::string, Variation>` | バリエーションキーをキーとする `Variation` オブジェクトのマップ。 |
| `rules` | `std::vector<Rule>` | `Rule` オブジェクトのリスト |

```cpp theme={null}
// Check whether the feature flag is enabled in the current environment.
bool environment_enabled = feature_flag.environment_enabled;

// Retrieve the key of the default variation.
const std::string& default_variation_key = feature_flag.default_variation_key;

// Retrieve the default variation object (nullptr if the key isn't in `variations`).
const Variation* default_variation = feature_flag.default_variation();

// Retrieve all variations of the feature flag as a map (key = variation key, value = Variation object).
const std::unordered_map<std::string, Variation>& variations = feature_flag.variations;

// Retrieve all targeting rules associated with the feature flag.
const std::vector<Rule>& rules = feature_flag.rules;
```

#### Rule

`Rule` は、ルール自体を定義するプロパティのセット(たとえば、その [`Variations`](#variation))を表します。

クライアントが必要とする場合、追加情報で拡張できます。詳細が必要な場合は、カスタマーサクセスマネージャーにお問い合わせください。

| 名前 | 型 | 説明 |
| - | - | - |
| `variations` | `std::unordered_map<std::string, Variation>` | バリエーションキーをキーとする `Variation` オブジェクトのマップ。 |

```cpp theme={null}
// Retrieve all variations of the rule as a map (key = variation key, value = Variation object)
const std::unordered_map<std::string, Variation>& variations = rule.variations;
```

#### Variation

`Variation` には、訪問者に割り当てられたバリエーション、または特定の割り当てが存在しない場合はデフォルトバリエーションに関する情報が含まれます。

| 名前 | 型 | 説明 |
| - | - | - |
| `name` | `std::string` | バリエーションの名前。 |
| `key` | `std::string` | バリエーションを識別する一意のキー。 |
| `id` | `std::optional<uint32_t>` | 割り当てられたバリエーションの ID。デフォルトバリエーションの場合は `std::nullopt`。 |
| `experiment_id` | `std::optional<uint32_t>` | バリエーションに関連付けられた実験の ID。デフォルトバリエーションの場合は `std::nullopt`。 |
| `variables` | `std::vector<Variable>` | バリエーションに関連付けられた変数。変数がアタッチされていない場合、このコレクションは空になることがあります。 |

<Note>
  * `Variation` は割り当てられたバリエーションまたはデフォルトバリエーションを記述し、[`Variable`](#variable) は個々の変数の詳細を含みます。
  * `id` と `experiment_id` は `std::nullopt` になる場合があり、これは特定の実験の割り当てに紐付いていないデフォルトバリエーションを示します。
</Note>

追加のヘルパーメソッド:

| メソッド | 戻り値の型 | 説明 |
| - | - | - |
| `active()` | `bool` | `off` バリエーションの場合は `false` を返します。 |
| `get_variable(key)` | `const Variable*` | 指定されたキーを持つバリエーション変数へのポインタを返します。見つからない場合は `nullptr` を返します。 |

```cpp theme={null}
// Retrieving the variation name
const std::string& variation_name = variation.name;

// Retrieving the variation key
const std::string& variation_key = variation.key;

// Retrieving the variation id
std::optional<uint32_t> variation_id = variation.id;

// Retrieving the experiment id
std::optional<uint32_t> experiment_id = variation.experiment_id;

// Retrieving the variables vector
const std::vector<Variable>& variables = variation.variables;

// Checking if the variation is active (i.e., currently being served to visitors)
bool is_active = variation.active();

// Retrieving a variable by its key, returning `nullptr` if not found
if (const Variable* variable = variation.get_variable("title")) {
    // Use `variable`.
}
```

#### Variable

`Variable` には、割り当てられたバリエーションに関連付けられた変数に関する情報が含まれます。

| 名前 | 型 | 説明 |
| - | - | - |
| `key` | `std::string` | 変数を識別する一意のキー。 |
| `kind` | `std::string` | 変数の型。可能な値には `BOOLEAN`、`NUMBER`、`STRING`、`JSON`、`JS`、`CSS` があります。 |
| `value` | [`JsonValue`](#jsonvalue) | 変数の値。`kind` に応じて、ブール値、数値、文字列、JSON 文字列、JavaScript スニペット、または CSS スニペットを保持できます。 |

```cpp theme={null}
// Retrieve the list of variables associated with the variation
const std::vector<Variable>& variables = variation.variables;

// Access the variable key
const std::string& variable_key = variable.key;

// Access the variable type (kind) for conditional handling
const std::string& kind = variable.kind;

// Extract the value as a number (returns `std::nullopt` if not a number)
std::optional<double> number = variable.value.as_number();

// Extract the value as a boolean (returns `std::nullopt` if not a boolean)
std::optional<bool> apply_discount = variable.value.as_bool();

// Extract the value as a string (returns `std::nullopt` if not a string-carrying kind)
std::optional<std::string> title = variable.value.as_string();
```

<a id="jsonvalue" />

##### JsonValue

`JsonValue` は、C++ におけるバリエーション変数の値を表します。`kind` フィールドは、文字列を保持する種類を区別します。`value` は `std::variant<bool, double, std::string>` です。

| 種類 | 保存される型 | 説明 |
| - | - | - |
| `JsonValueKind::Boolean` | `bool` | ブール値を表します。 |
| `JsonValueKind::Number` | `double` | 数値を表します。 |
| `JsonValueKind::String` | `std::string` | 文字列値を表します。 |
| `JsonValueKind::JSON` | `std::string` | JSON エンコードされた値を表します。 |
| `JsonValueKind::JS` | `std::string` | JavaScript コードスニペットを表します。 |
| `JsonValueKind::CSS` | `std::string` | CSS コードスニペットを表します。 |

型付きアクセサは、値が別の種類の場合に `std::nullopt` を返します:

| メソッド | 戻り値の型 | 説明 |
| - | - | - |
| `as_bool()` | `std::optional<bool>` | ブール値。 |
| `as_number()` | `std::optional<double>` | 数値。 |
| `as_string()` | `std::optional<std::string>` | 文字列を保持するすべての種類(`String`、`JSON`、`JS`、`CSS`)の文字列値。 |
