У меня есть программный компонент с 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. Однако это не работает с другие идентификаторы также являются typedefs без знака int (Я использую их для поддержания порядка и читабельности в моем коде и API).
Я также нашел Q&Здесь я не могу специализироваться на двух typedef, которые на самом деле одного и того же типа, и так как это просто числовые идентификаторы, я не хочу использовать структуры вместо int.
Любые идеи, как я могу вызвать мой APIMethod из шаблонной функции при соблюдении всех вышеуказанных требований?
Самым простым решением могут быть параметры шаблона по умолчанию, если это работает для вас:
typedef unsigned int CustomerId;
template <typename DataType, typename ID = CustomerId>
struct CommandResult
{
std::map<ID, DataType> data;
};
Если это не сработает, мое следующее предложение будет использовать BOOST_STRONG_TYPEDEF
создать все типы идентификаторов, которые не являются CustomerId, в результате чего каждый из них будет иметь отдельный тип, для которого вы можете создавать признаки.
Других решений пока нет …