Vous pouvez utiliser std::is_signed
avec std::enable_if
:
template<typename T>
T diff(T a, T b);
template<typename T>
std::enable_if_t<std::is_signed<T>::value, T> diff(T a, T b) {
return a - b;
}
Ici, std::is_signed<T>::value
est true
si et seulement si T
est signé (BTW, c'est aussi true
pour les types à virgule flottante, si vous n'en avez pas besoin, envisager de combiner avec std::is_integral
).
std::enable_if_t<Test, Type>
est le même que std::enable_if<Test, Type>::type
. std::enable_if<Test, Type>
est défini comme un vide struct en cas Test
est faux et qu'une structure avec un seul typedef type
égal au paramètre de modèle Type
sinon.
Donc, pour les types signés, std::enable_if_t<std::is_signed<T>::value, T>
est égal à T
, tandis que les non signés, ce n'est pas définie et le compilateur utilise SFINAE règle, donc, si vous avez besoin de spécifier une mise en œuvre pour un particulier non-signé, vous pouvez facilement le faire:
template<>
unsigned diff(unsigned, unsigned)
{
return 0u;
}
Quelques liens pertinents: enable_if, is_signed.