CでのC ++テンプレートタイプAPIの慣用的なラッピング


9

C関数でデータストア(Hazelcast)へのアクセスを提供するC ++ APIのラップに取り組んでいるため、データストアはCのみのコードからもアクセスできます。

Mapデータ構造用のHazelcast C ++ APIは次のようになります。

auto map = hazelcastClient->client->getMap<int, string>(mapName);
map.put(key, value);

とテンプレートのテンプレートタイプを使用keyvalueます。Cには利用可能なテンプレートがないため、getMap<T, U>メソッドの特殊化ごとにラッパー関数を作成することを考えました。つまり、Cタイプごとに。私があることを承知しているが、signedおよびunsignedCタイプのバージョンは、私だけをサポートするAPIを制限して大丈夫だよintdoublefloatchar *のためにkeyvalue

そこで、すべての組み合わせを自動生成する小さなスクリプトを書きました。エクスポートされた関数は次のようになります。

int Hazelcast_Map_put_int_string(
    Hazelcast_Client_t *hazelcastClient,
    const char *mapName,
    int key,
    char *value,
    char** errptr
);

int Hazelcast_Map_put_int_int(
    Hazelcast_Client_t *hazelcastClient,
    const char *mapName,
    int key,
    int value,
    char** errptr
);

...

機能の生成getsetcontainsすべての可能な組み合わせとkeyし、value種類は非常に多くのコードの量を増加させ、そして、私はコードを生成することは良いアイデアだと思いますが、それはコード生成インフラのいくつかの種類を作成することによって、追加の複雑さを追加します。

私が想像できるもう1つのアイデアは、次のようなCの一般的な関数の1つです。

int Hazelcast_Map_put(
    Hazelcast_Client_t *hazelcastClient,
    const char *mapName,

    const void *key,
    API_TYPE key_type,

    const void *value,
    API_TYPE value_type,

    char** errptr
);

これは次のように使用できます:

Hazelcast_Map_put(client, mapName, "key", API_TYPE_STR, "val", API_TYPE_STR, &err);

これにより、コードで正しい特殊化を取得する負担が軽減されるため、呼び出し元にとっては少し簡単になりますが、型の安全性が失われ、キャストが必要になります。また、intを渡すために、void *現在のkeyand のタイプとvalue同様(void *) (intptr_t) intValに、呼び出し側でキャストのようなものが必要になりますが、これもまた、読み取りと保守が非常に適切ではありません。

  • 認識できない3番目のオプションはありますか?
  • C開発者が好むバージョンはどれですか?

私は主にすべてのタイプの組み合わせを自動生成し、それぞれに関数を作成する傾向がありますが、ヘッダーファイルはかなり大きくなると思います。


多くの賛成票、まだ意見はありません。Cでテンプレート型メソッドをラップする方法はよくある問題です。
最大

それが一般的であるかどうかはわかりません。問題が興味深いと思うので賛成しました。
MetaFight 2016年

関連して、ではないが、本当にすべてがここに役立つ:stackoverflow.com/questions/1588788/...
マーティンBaの

回答:


1

すべての可能性を生み出すことは、私にとって非常に良い解決策とは思えませんでした。キーと値はオブジェクトでもかまいません。したがって、可能性は無限です:(

IMapImplクラスをご覧になりましたか?このクラスはタイプを使用せず、バイナリデータ(シリアル化後に提供される)を使用します。したがって、別の解決策は、このインターフェイスを模倣するAPIを作成し、任意の型をこのインターフェイスに必要なバイナリに変換するシリアル化ユーティリティを提供することです。

例えば

API:

struct Binary {
   byte *data;
   size_t length;
   int32_t dataType;
};
Binary *hazelcast_map_put(const Binary *key, const Binary *value);

シリアル化ユーティリティ:

int hazelcast_binary_to_int(const Binary *data);

サポートしたいオブジェクト型に対して、これらのヘルパー関数を作成する必要がある場合があります。これは実行可能なインターフェースかもしれません。メモリ管理などの考慮事項があります。

シリアル化は複雑なテーマですが、最初にプリミティブ型をサポートすることから始めることができます。http://docs.hazelcast.org/docs/3.6/manual/html-single/index.html#serializationおよびhttps://github.com/hazelcast/hazelcast/blob/master/hazelcast/src/main/javaを参照してくださいシリアル化の詳細については、/ com / hazelcast / internal / serialization / impl / ConstantSerializers.javaをご覧ください。


これが私の場合に行く方法だと思います。ループの外にいる人のために、hazelcast C ++クライアントgithub.com/hazelcast/hazelcast-cpp-client/pull/127にもPRで同じ質問をしました。そのC ++クライアントのメンテナーであるihsanは、ここでも私の質問に回答します。
最大
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.