Constructor call cannot appear in constant expression

I apologize for my newbie question, but I know little about C ++. Can someone answer why I get the error "error: constructor call cannot appear in constant expression" when compiling the following code;

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

I am using Ubuntu 12.04 and gcc which comes with it. This is not my code, and I know that this code probably works OK 100% (maybe in the old version of gcc or another compiler). Is there a quick way to fix this?

Thanks in advance for any answers, this is my first time when I ask something in SO.

+2
source share
3 answers

Call to a constructor cannot appear in a constant-expression - GCC error message that does not make sense to me. For example, Clang accepts your code with some warnings:

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

In any case, the initialization of double in the class of the class is non-standard. You must initialize separately:

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

and then exactly in one source file (and not in the 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 that have integer types in the body class, although this has been extended in C ++ 0x11. See Also Initializing a const member in a class declaration in C ++

+6
source

I just stumbled upon this same problem. The code we are discussing is part of the implementation of KIT shrinking hierarchies .

This is the only compilation error when trying to compile code with gcc 4.8.

The fix suggested by @vitaut is what is needed to complete this work. However, note that the following lines already exist in 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 the EliminationWeight.cpp file to go along with your EliminationWeight.h and include it in the Makefile, these lines cause you to see a different error than mentioned above:

 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 delete these lines in main.cpp, or use them for actual initialization. I went with the latter and now the lines 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 used the std::numeric_limits pattern for the type defined by EliminationWeight::Type typedef. This means that we need to change only this typedef type to use a different type.

However, using them in main.cpp, we include the header for the numeric_limits template. It also worked for me without including a header, but this is probably because it is included through some other file. For clean code purposes, we should include it anyway.

 #include <limits> 

Also note that C ++ 11 provides a new lowest function for the numeric_limits template, which means you can replace the last line as follows:

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

However, C ++ reference to lowest indicates the return value for floating point types as

Depends on implementation; usually negative of max ()

so I'm not sure how much you win using this feature. This gives you cleaner code, but it seems that the return value is somewhat unspecified.

+2
source

I had this problem when I was going to declare and instantiate a static const object of class Time inside the class Alg . This worked when I declare a member variable inside the class and instantiate this part, for example:

 Class Alg { public: . . static const Time genTime; . . } const Alg::genTime = Time(0,0,1,0); 
0
source

Source: https://habr.com/ru/post/1491589/


All Articles