我正在尝试使用模板编写“电源”功能。
#define VAR_X 2.0f
template <int N> struct Power
{
static const float ret = VAR_X * Power<N-1>::ret;
};
template <> struct Power<0>
{
static const float ret = 1.0f;
};
我为变量使用了一个宏,因为浮点数不能用作模板参数。当我尝试用g ++ 5.4.0编译时,我得到了这个:
tmptrig.cpp: In instantiation of ‘const float Power<1>::ret’:
tmptrig.cpp:35:28: required from here
tmptrig.cpp:17:24: error: the value of ‘Power<0>::ret’ is not usable in a constant expression
static const float ret = VAR_X * Power<N-1>::ret;
^
tmptrig.cpp:22:24: note: ‘Power<0>::ret’ does not have integral or enumeration type
static const float ret = 1.0f;
但是,当我将程序更改为仅处理整数时,它可以正常工作。
#define VAR_X 2
template <int N> struct Power
{
static const int ret = VAR_X * Power<N-1>::ret;
};
template <> struct Power<0>
{
static const int ret = 1;
};
我知道浮点数不能用作模板参数,但(据我所知)并不是这里的处理方式。当我使用浮动时,为什么编译器不喜欢它?
修改:这就是我main
的样子:
int main(int argc, char *argv[])
{
std::cout << Power<1>::ret << std::endl;
}
答案 0 :(得分:1)
问题不在于浮点数不能是常量表达式,因为它们可以(尽管不允许作为模板非类型参数)。问题是你的代码需要明确标记它们,或者它们不能在类定义本身中初始化。
#include <iostream>
float constexpr var_x = 2.0f;
template <int N> struct Power
{
static constexpr float ret = var_x * Power<N-1>::ret;
};
template <> struct Power<0>
{
static constexpr float ret = 1.0f;
};
int main(int argc, char *argv[])
{
std::cout << Power<1>::ret << std::endl;
}
它与原始意图几乎相同,因为constexpr
暗示const
。
Clang提供了有关原始代码的更有用的警告:
error: in-class initializer for static data member of type 'const float' requires 'constexpr' specifier [-Wstatic-float-init]
static const float ret = VAR_X * Power<N-1>::ret;
它们甚至可以在C ++ 03中成为常量表达式(以及元函数的结果),但这需要一个不合逻辑的定义:
float const var_x = 2.0f;
template <int N> struct Power
{
static const float ret;
};
template <int N>
const float Power<N>::ret = var_x * Power<N-1>::ret;
template <> struct Power<0>
{
static const float ret;
};
const float Power<0>::ret = 1.0f;
答案 1 :(得分:0)
publishedOn
版本的工作原因是因为它作弊。
如果非易失性非内联const静态数据成员是整数或枚举类型,则其在类定义中的声明可以指定一个括号或等于初始化器,其中每个初始化器 - 赋值表达式是一个常量表达式
有关如何实际编写正确的代码,请查看StoryTeller's answer