2

クライアントで維持する API を備えたソフトウェア コンポーネントがあります。以下は私の問題の単純化です。

これはインターフェースの一部です:

typedef unsigned int CustomerId;
template <typename DataType>
struct CommandResult
{
    std::map<CustomerId, DataType> data;
};

API には、次のような API メソッドの長いリストがあります。

APIResult APIMethod(input_parameters, CommandResult<SomeType>& output);

現在、少し異なる CommandResult を必要とするいくつかの新しい API メソッドを追加しています。したがって、これを GeneralCaseCommandResult と呼びます。

template <typename ID, typename DataType>
class GeneralCaseCommandResult 
{
    std::map<ID, DataType> data;
};

テンプレートを使用して内部で多くのコードを再利用するため、両方の CommandResult 型を同じ構造体に保持することは非常に便利です。

ただし、CommandResult を置き換えるためだけにクライアントに多くのコードを変更するよう強制したくないので、次のようにしました。

template <typename DataType>
class CommandResult : public GeneralCaseCommandResult<CustomerId, DataType> {};

そしてすべてが桃色です。

ここで、次のように、テンプレート化された関数の一部から API メソッドを呼び出したいと考えています。

template <typename ID, typename DataType>
void MyInternalFunc()
{
    GeneralCaseCommandResult<ID, DataType> output;

    // Will not compile
    APIResult res = APIMethod(params, output);

    ...
}

既存の API メソッドは基本クラスではなく CommandResult を受け取るため、これはもちろん機能しません。

ID/DataType ごとに特性クラスを作成して CommandResult タイプを保持し、それを CustomerId に特殊化して CommandResult をサポートしようとしました。ただし、他の ID も unsigned int の typedef であるため、機能しません(コードと API の順序と読みやすさを維持するために使用しています)。

また、実際には同じ型である 2 つの typedef を特殊化できないという Q&A も見つかりました。これらは単なる数値 ID であるため、int の代わりに構造体を使用したくありません。

上記のすべての要件を維持しながら、テンプレート化された関数内から APIMethod を呼び出す方法はありますか?

4

1 に答える 1

1

最も簡単な解決策は、デフォルトのテンプレート パラメータである可能性があります。

typedef unsigned int CustomerId;
template <typename DataType, typename ID = CustomerId>
struct CommandResult
{
    std::map<ID, DataType> data;
};

それがうまくいかない場合、私の次の提案は、BOOST_STRONG_TYPEDEFCustomerId ではないすべての id タイプを作成するために使用することです。これにより、それぞれが特性を作成できる個別のタイプになります。

于 2013-06-18T21:23:14.680 に答える