我有一个软件组件,其中包含我与客户一起维护的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创建一个traits类来保存CommandResult类型,并在CustomerId上专门设置它以支持CommandResult。但是它不起作用,因为其他ID也是unsigned int的typedef (我使用它们来维护我的代码和API中的顺序和可读性)。
我在这里也发现Q&amp; A我不能专注于两个实际上是同一类型的typedef,因为这些只是数字ID,我不想使用结构而不是int。
如何在保留所有上述要求的同时从模板化函数中调用我的APIMethod的任何想法?
答案 0 :(得分:1)
最简单的解决方案可能是默认模板参数,如果适用于您:
typedef unsigned int CustomerId;
template <typename DataType, typename ID = CustomerId>
struct CommandResult
{
std::map<ID, DataType> data;
};
如果不能解决这个问题,我的下一个建议是使用BOOST_STRONG_TYPEDEF
来创建非CustomerId的所有id类型,从而使每个类型成为可以为其创建特征的不同类型。 / p>