Прежде чем вы сможете специализовать шаблон, вы сначала должны ввести его вообще:
template<typename Edge, typename DurationType>
std::chrono::time_point time_sum(std::chrono::time_point tp, DurationType inc);
template<typename DurationType>
std::chrono::time_point time_sum<ForwardEdge, DurationType>( /*...*/ )
// ^^^ ^^^
// you still need to specify ALL template parameters!
Исключительно: это частичная специализация! Вам не разрешено частично специализировать функции, вам разрешено только делать это для типов .
Так что нам нужен вспомогательный класс:
template<typename Edge, typename DurationType>
struct TimeSum;
template<typename DurationType>
struct TimeSum<ForwardEdge, DurationType>
{
std::chrono::time_point operator()(std::chrono::time_point tp, DurationType d)
{
return tp + d;
}
};
template<typename DurationType>
struct TimeSum<ReverseEdge>
{
std::chrono::time_point operator()(std::chrono::time_point tp, DurationType d)
{
return tp - d;
}
};
Теперь мы можем использовать типы в совершенно не специализированной функции:
template<typename Edge, typename DurationType>
std::chrono::time_point time_sum(std::chrono::time_point tp, DurationType inc)
{
return TimeSum<Edge, DurationType>()(tp, inc);
// ^^^
// selects appropriate partial specialisation
}
Пока мы получаем только эти две специализации, любые другие экземпляры шаблона остаются неопределенными. Вариант может быть:
template<typename Edge, typename DurationType>
{
std::chrono::time_point operator()(std::chrono::time_point tp, DurationType d)
{
return tp + d;
}
};
// and the specialisation for ReverseEdge from above
В этом сценарии у вас есть общий шаблон, который работает для любого типа, не охватываемого специализацией (включая ForwardEdge
), и специализация, специфичная для ReverseEdge
. Учитывая имя типа (TimeSum
), этот вариант может быть более подходящим.
Поскольку параметр функции ребра отсутствует, вам необходимо указать аргумент шаблона вручную. Если у вас do все равно есть ребра, перегрузки могут быть лучшим выбором:
template<typename DurationType>
std::chrono::time_point time_sum
(
ForwardEdge const&, // <--
std::chrono::time_point tp, DurationType inc
);
template<typename DurationType>
std::chrono::time_point time_sum
(
ReverseEdge const&, // <--
std::chrono::time_point tp, DurationType inc
);
Другой альтернативой может быть наличие member функций в каждом классе (возможно, даже виртуальных,если они имеют общую базу).