Итак, если я правильно понимаю, вы компилируете C ++ 14, но ваш компилятор не полностью совместим с функциями C ++ 14 constexpr
.Так что вы не можете сделать цикл внутри constexpr
функции.
Ну ... у меня нет вашего компилятора, поэтому я не знаю, что именно ваш компилятор не поддерживает, поэтому я предлагаюрешение C ++ 14, основанное на нерекурсивной шаблонной функции constexpr
variadic, которая не использует цикл for.Ну ... две функции: одна для отрицательных степеней и одна для неотрицательных степеней.
Надеемся, что VS2015 его поддержит.
Отрицательной функцией является следующий
template
constexpr T negPow10 (std::index_sequence<Is...> const &)
{
using unused = std::size_t[];
T ret { 1 };
(void)unused { 0U, (ret /= 10, Is)... };
return ret;
}
Неотрицательный (для положительных или нулевых степеней) почти равен, но используйте ret *= 10
вместо ret /= 10
.
Они вызываются через следующие
template <typename T, int E, std::size_t N = (E < 0 ? -E : E)>
constexpr T pow10 ()
{ return E < 0
? negPow10<T>(std::make_index_sequence<N>{})
: posPow10<T>(std::make_index_sequence<N>{}); }
Ниже приведен полный пример компиляции (но обратите внимание, что, как указывает nm, static_assert()
над double
power не является надежным)
#include <utility>
template <typename T, std::size_t ... Is>
constexpr T posPow10 (std::index_sequence<Is...> const &)
{
using unused = std::size_t[];
T ret { 1 };
(void)unused { 0U, (ret *= 10, Is)... };
return ret;
}
template <typename T, std::size_t ... Is>
constexpr T negPow10 (std::index_sequence<Is...> const &)
{
using unused = std::size_t[];
T ret { 1 };
(void)unused { 0U, (ret /= 10, Is)... };
return ret;
}
template <typename T, int E, std::size_t N = (E < 0 ? -E : E)>
constexpr T pow10 ()
{ return E < 0
? negPow10<T>(std::make_index_sequence<N>{})
: posPow10<T>(std::make_index_sequence<N>{}); }
int main ()
{
static_assert( pow10<long, 5>() == 1e5, "!" );
static_assert( pow10<double, -3>() == 1e-3, "!" );
}
Если честно, эторешение является (или может быть) немного рекурсивным в std::make_index_sequence
.