Mógłbyś użyć częściowej specjalizacji w taki sposób:
template<typename ReturnType, typename Type, typename... Args>
ReturnType average(const Type &value, Args... nextArgs) { std::cout << "primary\n"; }
template<typename ReturnType, typename Type, typename... Args>
ReturnType average<ReturnType, NotAlwaysCountable<Type>, Args...>(const NotAlwaysCountable<Type> &value,Args... nextArgs) { std::cout << "NotAlwaysCountable<Type>\n"; }
ale standard niestety zabrania częściowej specjalizacji funkcji (tak, kod powyżej nie powinien się skompilować; chociaż msvc to ogarnia o ile dobrze kojarze). Można to jednak łatwo obejść opakowując funkcje w klase, ale wtedy przy każdym wywołaniu jesteś zmuszony podawać parametry szablonu :/ Innej opcji niestety nie widze.
Edit: Wykminiłem troche lepiej i rozszerzam odpowiedź. Zawołanie do metody wyspecjalizownej częściowo klasy opakowuje w szablon funkcji, który już nie potrzebuje specjalizacji:
template<typename ReturnType, typename Type, typename... Args>
struct Utils
{
static ReturnType average(const Type &value, Args... nextArgs) { std::cout << "primary\n"; }
};
template<typename ReturnType, typename Type, typename... Args>
struct Utils<ReturnType, NotAlwaysCountable<Type>, Args...>
{
static ReturnType average(const NotAlwaysCountable<Type> &value, Args... nextArgs) { std::cout << "NotAlwaysCountable<Type>\n"; }
};
Poniżej kod dodany przy edicie:
template<typename R, typename ...Args>
R average(Args... args)
{
return Utils<R, Args...>::average(std::forward<Args>(args)...);
}
live przykład