J'ai une méthode en C# comme suit (qui enveloppe un nombre dans une plage, disons 0 à 360 ... si vous passez 0-359 vous obtenez la même valeur, si vous passez 360 vous obtenez 0, 361 obtient 1, etc.):Type conditionnel dans les modèles C++?
/// <summary>
/// Wraps the value across the specified boundary range.
///
/// If the value is in the range <paramref name="min"/> (inclusive) to <paramref name="max"/> (exclusive),
/// <paramref name="value"/> will be returned. If <paramref name="value"/> is equal to <paramref name="max"/>,
/// <paramref name="min"/> will be returned. The method essentially creates a loop between <paramref name="min"/>
/// and <paramref name="max"/>.
/// </summary>
/// <param name="value">The value to wrap.</param>
/// <param name="min">The minimum value of the boundary range, inclusive.</param>
/// <param name="max">The maximum value of the boundary range, exclusive.</param>
/// <returns>The value wrapped across the specified range.</returns>
public static T Wrap<T>(T value, T min, T max) where T : IComparable<T>
{
// If it's positive or negative infinity, we just return the minimum, which is the "origin"
bool infinityDouble = typeof(T) == typeof(double) && (double.IsPositiveInfinity(Convert.ToDouble(value)) || double.IsNegativeInfinity(Convert.ToDouble(value)));
bool infinityFloat = typeof(T) == typeof(float) && (float.IsPositiveInfinity(Convert.ToSingle(value)) || float.IsNegativeInfinity(Convert.ToSingle(value)));
if (infinityDouble || infinityFloat)
{
return min;
}
// If the value is between the origin (inclusive) and the maximum value (exclusive), just return the value
if (value.CompareTo(min) >= 0 && value.CompareTo(max) < 0)
{
return value;
}
// The range of the wrapping function
var range = (dynamic)max - (dynamic)min;
return ((((value % range) + range) - min) % range) + min;
}
J'ai aussi besoin de cette méthode en C++, que je définis comme suit:
/*!
Wraps the value across the specified boundary range.
If the value is in the range \a min (inclusive) to \a max (exclusive), \a value will be returned.
If \a value is equal to \a max, \a min will be returned. The method essentially creates a loop between
\a min and \a max.
\param value The value to wrap.
\param min The minimum value of the boundary range, inclusive.
\param max The maximum value of the boundary range, exclusive.
\return The value wrapped across the specified range.
*/
template <typename T> const T& MathHelper::wrap(const T &value, const T &min, const T &max)
{
// If it's positive or negative infinity, we just return the minimum, which is the "origin"
bool infinityDouble = value == std::numeric_limits<double>::infinity() || value == -std::numeric_limits<double>::infinity();
bool infinityFloat = value == std::numeric_limits<float>::infinity() || value == -std::numeric_limits<float>::infinity();
if (infinityDouble || infinityFloat)
{
return min;
}
// If the value is between the origin (inclusive) and the maximum value (exclusive), just return the value
if (value >= min && value < max)
{
return value;
}
// The range of the wrapping function
T range = max - min;
return ((((value % range) + range) - min) % range) + min;
}
maintenant, ma question est la suivante: suis-je contrôle pour l'infini correctement dans la version C++? Je ne vois aucun moyen de dire "si double, faites ces vérifications, si elles flottent, faites ces vérifications". Si ce n'est pas le type que je veux, est-ce que ça retournera faux? En outre, pourquoi l'opérateur% n'est-il pas défini pour float et double? Je suppose que je vais devoir implémenter moi-même l'opérateur modulo. La méthode est plutôt destinée aux types numériques - byte, short, int, long, float, double.
« si double, ne ces contrôles, si flotteur, font ces contrôles » -> qui est ce que la spécialisation de modèle est pour – Colin
Oui, j'oublièrent la spécialisation ... mais ceux-ci sont des méthodes individuelles qui doivent être spécialisées, donc c'est plus de surcharge que de spécialisation. –