2013-06-18 1 views
2

У меня есть программный компонент с API, который я поддерживаю с клиентами. Ниже приводится упрощение моей проблемы.Добавление параметра шаблона в структуру 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 unsigned int (я использую их для поддержания порядка и удобочитаемости в моем коде и API).

Я также нашел Q & A здесь, что я не могу специализироваться на двух typedefs, которые на самом деле одного и того же типа, и поскольку это просто числовые идентификаторы, я не хочу использовать structs вместо int.

Любые идеи о том, как я могу назвать свой APIMethod из шаблонной функции, сохраняя при этом все вышеуказанные требования?

ответ

1

Самым простым решением может быть параметры шаблона по умолчанию, если это работает для вас:

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

Если это не сделать трюк мое следующее предложение было бы использовать BOOST_STRONG_TYPEDEF для создания всех типов идентификаторов, которые Арен 't CustomerId, заставляя каждого быть отдельным типом, для которого вы можете создавать черты.

+0

Это кажется настолько очевидным, когда я перечитываю название на свой вопрос ... Работает как шарм. Благодарю. – Asaf

 Смежные вопросы

  • Нет связанных вопросов^_^