关于c ++:对构造函数的调用不能出现在常量表达式中


Call to a constructor cannot appear in a constant-expression

我很抱歉我的新问题,但我不知道很多关于C++。在编译以下代码时,是否有人能回答我为什么会出现错误"错误:对构造函数的调用不能出现在常量表达式中";

1
2
3
4
5
6
7
class EliminationWeight
{
 public:
    typedef double Type;
    static const Type MAX_VALUE = __DBL_MAX__;
    static const Type MIN_VALUE = -__DBL_MAX__;
};

我使用Ubuntu12.04和附带的GCC。这不是我的代码,我知道这段代码可能100%正常工作(可能在旧版本的gcc或其他编译器中)。有没有一个快速的方法来解决它?

事先谢谢你的回答,这是我第一次这么问。


Call to a constructor cannot appear in a constant-expression是一条gcc错误消息,在这里对我来说并没有真正意义。例如,Clang接受您的代码并发出一些警告:

1
2
3
4
test.cpp:31:23: warning: in-class initializer for static data member of type
      'const Type' (aka 'const double') is a GNU extension [-Wgnu]
    static const Type MAX_VALUE = __DBL_MAX__;
                      ^           ~~~~~~~~~~~

无论如何,在类体中初始化double是不标准的。您应该单独进行初始化:

1
2
3
4
5
6
7
class EliminationWeight
{
 public:
    typedef double Type;
    static const Type MAX_VALUE;
    static const Type MIN_VALUE;
};

然后在一个源文件中(不是头文件):

1
2
const EliminationWeight::Type EliminationWeight::MAX_VALUE = __DBL_MAX__;
const EliminationWeight::Type EliminationWeight::MIN_VALUE = -__DBL_MAX__;

通常,您只能在类体中初始化具有整型类型的静态成员变量,尽管这在C++0x11中已被扩展。请参阅C++中类声明中的const成员初始化


我只是偶然发现了这个完全相同的问题。我们讨论的代码是Kit实现的收缩层次结构的一部分。

这是在使用GCC4.8编译代码时给出的唯一编译错误。

@vitaut建议的修复程序是使此工作正常所必需的。但是,请注意,main.cpp中已经存在以下行:

1
2
3
4
// doesn't look nice, but required by the compiler (gcc 4)
...
const EliminationWeight::Type EliminationWeight::MAX_VALUE;
const EliminationWeight::Type EliminationWeight::MIN_VALUE;

如果您决定创建一个eliminationweight.cpp文件与eliminationweight.h一起并将其包含在makefile中,那么这些行就是您看到与上述不同错误的原因:

1
2
3
4
5
6
main.cpp:86:31: error: uninitialized const ‘EliminationWeight::MAX_VALUE[-fpermissive]
 const EliminationWeight::Type EliminationWeight::MAX_VALUE;
                               ^
main.cpp:87:31: error: uninitialized const ‘EliminationWeight::MIN_VALUE[-fpermissive]
 const EliminationWeight::Type EliminationWeight::MIN_VALUE;
                               ^

解决方案是在main.cpp中删除这些行,或者将它们用于实际的初始化。我已经使用了后者,现在的行如下所示:

1
2
const EliminationWeight::Type EliminationWeight::MAX_VALUE = std::numeric_limits< EliminationWeight::Type >::max();
const EliminationWeight::Type EliminationWeight::MIN_VALUE = -std::numeric_limits< EliminationWeight::Type >::max();

注意,我已经使用了std::numeric_limits模板来定义EliminationWeight::Typetypedef定义的类型。这意味着我们只需要将typedef更改为使用其他类型。

但是,在main.cpp中使用这些命令要求我们包含numeric_limits模板的头文件。它也适用于我,不包括头部,但这可能是因为它是通过其他包含的文件包含的。为了干净的代码,我们无论如何都应该包括它。

1
#include <limits>

还请注意,C++ 11为EDCOX1×3模板提供了一个新的函数lowest,这意味着您可以用下面的方法替换最后一行:

1
const EliminationWeight::Type EliminationWeight::MIN_VALUE = std::numeric_limits< EliminationWeight::Type >::lowest();

但是,在EDCOX1(4)中的C++引用指定了浮点类型的返回值。

implementation-dependent; generally, the negative of max()

所以我不确定你是否通过使用这个函数获得了很多。它确实为您提供了外观更清晰的代码,但似乎返回值有些未指定。


当我要在类Alg中声明和实例化类Time的静态const对象时,遇到了这个问题。当我在类内部声明成员变量并在外部实例化它时,它就工作了,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
Class Alg {

    public:
    .
    .

    static const Time genTime;
    .
    .
}

const Alg::genTime = Time(0,0,1,0);