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

现在我添加了一些新的 API 方法,它们需要稍微不同的 CommandResult。所以我们称它为 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 中的顺序和可读性)。

我还在这里找到了问答,我不能专注于两个实际上是相同类型的 typedef,因为这些只是数字 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_TYPEDEF创建所有不是 CustomerId 的 id 类型,从而使每个类型都是您可以为其创建特征的不同类型。

于 2013-06-18T21:23:14.680 回答