Как можно наиболее грамотно проверить результат выполнения арифметической операции (допустим, сложения) на предмет выхода за пределы, предоставляемые данными фундаментальными типами?
Например, нам необходимо сложить две переменные типа int, результат сложения которых будет приводить к переполнению. Что можно сделать?
Итак, что я делал на данный момент:
#include <iostream>
#include <limits>
int add (int x, int y)
{
if ((x > 0 && y > 0 && x > (std::numeric_limits <int>::max () - y)) ||
(x < 0 && y < 0 && x < (std::numeric_limits <int>::min () - y)))
{
std::cout << "Error" << std::endl;
exit (EXIT_FAILURE);
}
else
{
return (x + y);
}
}
int main ()
{
int a = add (25, 10);
std::cout << a << std::endl;
int b = add (std::numeric_limits <int>::max (), std::numeric_limits <int>::max ());
return 0;
}
Всё это, разумеется, можно шаблонизировать:
template <typename T>
T add (T x, T y)
{
if ((x > 0 && y > 0 && x > (std::numeric_limits <T>::max () - y)) ||
(x < 0 && y < 0 && x < (std::numeric_limits <T>::min () - y)))
{
std::cout << "Error" << std::endl;
exit (EXIT_FAILURE);
}
else
{
return (x + y);
}
}
Но является ли этот способ оптимальным? Может, есть что-то лучше?