Visual studio 2015 constexpr以非递归方式的幂为10?

Visual studio 2015 constexpr以非递归方式的幂为10?,visual-studio-2015,c++14,template-meta-programming,constexpr,pow,Visual Studio 2015,C++14,Template Meta Programming,Constexpr,Pow,以递归方式实现10的幂很容易: template<int exp, bool = (exp > 0)> struct pow10 { static constexpr double value = pow10<exp - 1>::value * 10.0; }; template<> struct pow10<0, false> { static constexpr double value = 1.0; }; templ

以递归方式实现10的幂很容易:

template<int exp, bool = (exp > 0)>
struct pow10 {
    static constexpr double value = pow10<exp - 1>::value * 10.0;
};

template<>
struct pow10<0, false> {
    static constexpr double value = 1.0;
};

template<int exp>
struct pow10<exp, false> {
    static constexpr double value = pow10<exp + 1>::value / 10.0;
};

template<int exp>
static constexpr double pow10_v = pow10<exp>::value;

static_assert(pow10_v<-3> == 1e-3, "");
static_assert(pow10_v<2> == 1e2, "");
模板0)>
结构pow10{
static constexpr double value=pow10::value*10.0;
};
模板
结构pow10{
静态constexpr双值=1.0;
};
模板
结构pow10{
静态constexpr double value=pow10::value/10.0;
};
模板
静态constexpr double pow10_v=pow10::value;
静态断言(pow10\U v==1e-3,“”);
静态断言(pow10\U v==1e2,“”);
是否可以以非递归方式使
constexpr
的幂为10


仅供参考,我使用的VS2015在C++14中不支持relaxed-
constexpr
,因此,我不能在
constexpr
函数中使用for循环。

因此,如果我理解正确,您可以编译C++14,但您的编译器不完全符合C++14
constexpr
函数。因此,您不能在
constexpr
函数中进行循环

嗯。。。我没有你的编译器,所以我不知道你的编译器到底不支持什么,所以我提出了一个基于非递归
constepr
variadic模板函数的C++14解决方案,该函数不使用for循环。好。。。两个功能:一个用于负面权力,一个用于非负面权力

希望你能支持它

负函数如下

模板

constexpr T negPow10 (std::index_sequence<Is...> const &)
 {
   using unused = std::size_t[];

   T ret { 1 };

   (void)unused { 0U, (ret /= 10, Is)... };

   return ret;
 }
下面是一个完整的编译示例(但请注意,正如n.m.所指出的那样,
static\u assert()
double
电源上是不可靠的)

#包括
模板
constexpr T posPow10(std::index_sequence const&)
{
使用unused=std::size_t[];
T ret{1};
(无效)未使用的{0U,(ret*=10,Is);
返回ret;
}
模板
constexpr T negPow10(std::index_sequence const&)
{
使用unused=std::size_t[];
T ret{1};
(无效)未使用的{0U,(ret/=10,Is);
返回ret;
}
模板
constexpr T pow10()
{返回E<0
?negPow10(标准::生成索引序列{})
:posPow10(std::make_index_sequence{});}
int main()
{
静态断言(pow10()==1e5,“!”;
静态断言(pow10()==1e-3,“!”;
}

老实说,这个解决方案在
std::make_index_sequence

中有点递归,因此,如果我理解正确,您可以编译C++14,但您的编译器不完全符合C++14
constepr
函数。因此,您不能在
constexpr
函数中进行循环

嗯。。。我没有你的编译器,所以我不知道你的编译器到底不支持什么,所以我提出了一个基于非递归
constepr
variadic模板函数的C++14解决方案,该函数不使用for循环。好。。。两个功能:一个用于负面权力,一个用于非负面权力

希望你能支持它

负函数如下

模板

constexpr T negPow10 (std::index_sequence<Is...> const &)
 {
   using unused = std::size_t[];

   T ret { 1 };

   (void)unused { 0U, (ret /= 10, Is)... };

   return ret;
 }
下面是一个完整的编译示例(但请注意,正如n.m.所指出的那样,
static\u assert()
double
电源上是不可靠的)

#包括
模板
constexpr T posPow10(std::index_sequence const&)
{
使用unused=std::size_t[];
T ret{1};
(无效)未使用的{0U,(ret*=10,Is);
返回ret;
}
模板
constexpr T negPow10(std::index_sequence const&)
{
使用unused=std::size_t[];
T ret{1};
(无效)未使用的{0U,(ret/=10,Is);
返回ret;
}
模板
constexpr T pow10()
{返回E<0
?negPow10(标准::生成索引序列{})
:posPow10(std::make_index_sequence{});}
int main()
{
静态断言(pow10()==1e5,“!”;
静态断言(pow10()==1e-3,“!”;
}

老实说,这个解决方案在
std::make_index_sequence

中有点递归,“在编译时计算”与“常量表达式”或“constexpr”不同。如果您想要一个常量表达式,那么“否”(不确定为什么您也想要一个)。大多数现代编译器都乐于在编译时计算
pow
。请注意,
pow(10,-3)=1e-3
,在运行时或编译时计算,@n.m.谢谢。我编辑这个问题是为了弄清楚。它必须是一个模板元程序吗?使用标记粘贴创建
1E
的宏如何?为什么需要constepr,为什么需要非递归解决方案?@Barmar我需要模板元函数@n、 嗯,从根本上说,我只是想知道这种技术
constexpr
必须将其用作元函数。“编译时计算”与“常量表达式”或“constexpr”不同。如果您想要一个常量表达式,那么“否”(不确定为什么您也想要一个)。大多数现代编译器都乐于在编译时计算
pow
。请注意,
pow(10,-3)=1e-3
,在运行时或编译时计算,@n.m.谢谢。我编辑这个问题是为了弄清楚。它必须是一个模板元程序吗?使用标记粘贴创建
1E
的宏如何?为什么需要constepr,为什么需要非递归解决方案?@Barmar我需要模板元函数@n、 嗯,从根本上说,我只是想知道这种技术
constexpr
是将其用作元函数所必需的。VS 2015似乎无法编译这些c++14构造中的任何一个。@n.m.-这正是我所担心的:如果它不支持for循环,
constexpr
支持应该是C++11级别的。重复乘以或除以10将失去较大指数的精度。VS 2015似乎无法编译这些C++14构造。@n.m.-这正是我担心的:如果它不支持for循环,预计
constexpr
支持在C++11级别。重复乘以或除以10将失去较大指数的精度。
#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, "!" );
 }