简体   繁体   English

对构造函数的调用不能出现在常量表达式中

[英]Call to a constructor cannot appear in a constant-expression

I am sorry for my newbie question, but I do not know much about C++. 我很抱歉我的新手问题,但我对C ++知之甚少。 Can anybody answer why I get the error "error: a call to a constructor cannot appear in a constant-expression" when compiling following code; 任何人都可以回答为什么我在编译下面的代码时得到错误“错误:对构造函数的调用不能出现在常量表达式中”;

class EliminationWeight
{
 public:
    typedef double Type;
    static const Type MAX_VALUE = __DBL_MAX__;
    static const Type MIN_VALUE = -__DBL_MAX__;
};

I use Ubuntu 12.04 and gcc that comes with it. 我使用Ubuntu 12.04和随附的gcc。 It is not my code and I know that this code probably it works OK 100% (perhaps in older version of gcc or other compiler). 这不是我的代码,我知道这个代码可能100%正常工作(可能在旧版本的gcc或其他编译器中)。 Is there a quick way to fix it? 有没有快速解决方法?

Thanks in advance for any answers, this is actually my first time asking something at SO. 在此先感谢您的回答,这实际上是我第一次问SO。

Call to a constructor cannot appear in a constant-expression is a GCC error message which doesn't really make sense to me here. Call to a constructor cannot appear in a constant-expression是一个GCC错误消息,这对我来说真的没有意义。 Clang, for instance, accepts your code with some warnings: 例如,Clang接受您的代码并发出一些警告:

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__;
                      ^           ~~~~~~~~~~~

Anyway, initializing double in a class body is non-standard. 无论如何,在类体中初始化double是非标准的。 You should do initialization separately: 你应该单独进行初始化:

class EliminationWeight
{
 public:
    typedef double Type;
    static const Type MAX_VALUE;
    static const Type MIN_VALUE;
};

and then in exactly one source file (not a header file): 然后在一个源文件(不是头文件)中:

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

In general, you can only initialize static member variables having integral types in class body, although this has been extended in C++ 0x11. 通常,您只能在类体中初始化具有整数类型的静态成员变量,尽管这已在C ++ 0x11中进行了扩展。 See also Initializing const member within class declaration in C++ 另请参见在C ++中的类声明中初始化const成员

I just stumbled across this exact same problem. 我偶然发现了同样的问题。 The code we are discussing is part of the Contraction Hierarchies implementation by KIT . 我们讨论的代码是KITContraction Hierarchies实现的一部分。

This is the only compilation error given when trying to compile the code with gcc 4.8. 这是尝试使用gcc 4.8编译代码时唯一的编译错误。

The fix suggested by @vitaut is what is needed to make this work. @vitaut建议的修复是使这项工作所需要的。 However, note that there are already the following lines lingering in main.cpp: 但请注意,main.cpp中已经存在以下行:

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

If you decide to create an EliminationWeight.cpp file to go along with your EliminationWeight.h and include it in the Makefile, these lines are the reason why you are seeing a different error than mentioned above: 如果您决定创建一个EliminationWeight.cpp文件以与EliminationWeight.h一起使用并将其包含在Makefile中,这些行就是您看到与上面提到的错误不同的原因:

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;
                               ^

The solution is to either remove these lines in main.cpp or use them for the actual initialization. 解决方案是在main.cpp中删除这些行,或者将它们用于实际初始化。 I have gone with the latter and the lines now look like this: 我已经使用了后者,现在的行看起来像这样:

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

Note that I have used the std::numeric_limits template for the type defined by the EliminationWeight::Type typedef. 请注意,我已将std::numeric_limits模板用于由EliminationWeight::Type typedef定义的EliminationWeight::Type This means we only need to change that typedef to use a different type. 这意味着我们只需要更改typedef即可使用其他类型。

However, using these in main.cpp mandates that we include the header for the numeric_limits template. 但是,在main.cpp中使用这些命令要求我们包含numeric_limits模板的标头。 It also worked for me without including the header but that is probably because it is included via some other included file. 它也适用于我,但不包括标题,但这可能是因为它包含在其他包含的文件中。 For the purpose of clean code we should include it anyway. 出于清洁代码的目的,我们应该包括它。

#include <limits>

Also note that C++11 provides a new function lowest for the numeric_limits template meaning you could substitue the last line with the following: 另请注意,C ++ 11为numeric_limits模板提供了lowest的新函数,这意味着您可以使用以下内容替换最后一行:

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

However, the C++ reference on lowest specifies the return value for floating point types as 但是, lowestC ++引用将浮点类型的返回值指定为

implementation-dependent; 依赖于实现; generally, the negative of max() 通常,max()的负数

so I am not sure whether you gain much by using this function. 所以我不确定你是否通过使用这个功能获得了很多。 It does give you cleaner looking code but it seems the return value is somewhat unspecified. 它确实为您提供了更清晰的代码,但似乎返回值有点未指定。

I had this problem when I was going to declare and instantiate a static const object of class Time inside a class Alg . 当我要在类Alg声明并实例化类Time的静态const对象时,我遇到了这个问题。 It worked when I declare the member variable inside the class and instantiate it out side, like this: 它在我在类中声明成员变量并将其实例化出来时起作用,如下所示:

Class Alg {

    public: 
    .
    .

    static const Time genTime;
    .
    .
}

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM