Я сделал несколько шаблонов, которые, как предполагается,
[*] (1) Проверка, если числа можно добавить без переполнения,
(2) Добавить числа и сбой в случае переполнения. IS contexpr < /code>.
Я хотел избежать дублирования математики, поэтому я попытался поместить утверждение непосредственно внутри (2) функции, которая рассчитывает сумму. Можно ли это быть решено каким-либо образом?#include
#include
#include
template
constexpr bool add(T& a, T b)
{
static_assert(std::is_integral::value, "Only integral types are supported");
if ((b > 0) && (a > std::numeric_limits::max() - b))
return false;
if ((b < 0) && (a < std::numeric_limits::min() - b))
return false;
a += b;
return true;
}
//
template
constexpr bool sum_impl(T& result)
{
return true;
}
template
constexpr bool sum_impl(T& result, T value, Rest... rest)
{
if (!add(result, value))
return false;
return sum_impl(result, rest...);
}
//
template
constexpr bool test_sum(T value, Rest... rest) // (1)
{
return sum_impl(value, rest...);
}
template
T sum(T value, Rest... rest) // (2) regular
{
if (!sum_impl(value, rest...))
throw std::overflow_error("Overflow in checked::sum");
return value;
}
template
constexpr T sum_cexpr(T value, Rest... rest) // (2) constexpr
{
// if (!sum_impl(value, rest...))
// static_assert(false, "Overflow"); // fail
// static_assert(sum_impl(value, rest...), "Overflow"); // fail
// if (!sum_impl(value, rest...))
// delegated_assert(); // fail
return value;
}
template
constexpr void delegated_assert()
{
if constexpr (!B)
static_assert(B);
}
//////
int main()
{
static_assert(test_sum(1, 2)); // (1) works
constexpr int a = sum_cexpr(10, 20, 30); // fails to compile
return 0;
}
Подробнее здесь: https://stackoverflow.com/questions/795 ... tic-assert