Initialization of a const member in a class declaration in C ++

In PHP and C #, constants can be initialized as they are declared:

class Calendar3 { const int value1 = 12; const double value2 = 0.001; } 

I have the following declaration of a C ++ functor, which is used with another class to compare two mathematical vectors:

 struct equal_vec { bool operator() (const Vector3D& a, const Vector3D& b) const { Vector3D dist = b - a; return ( dist.length2() <= tolerance ); } static const float tolerance = 0.001; }; 

This code compiled without problems with g ++. Now in C ++ 0x mode (-std = C ++ 0x) the g ++ compiler displays an error message:

error: 'constexpr needed to initialize a static data class in a class, for a non-integer type

I know that I can define and initialize this static const member outside the class definition. In addition, a non-static constant data element can be initialized in the constructor initializer list.

But is there a way to initialize a constant in a class declaration in the same way as is possible in PHP or C #?

Update

I used the static only because it was possible to initialize such constants in a class declaration in g ++. I just need a way to initialize a constant in a class declaration, regardless of whether it is declared as static or not.

+59
c ++ g ++
Feb 04 2018-12-12T00:
source share
6 answers

In C ++ 11, members of the non static class, data members static constexpr and static const data members of an integral or enumerated type can be initialized in the class declaration. eg.

 struct X { int i=5; const float f=3.12f; static const int j=42; static constexpr float g=9.5f; }; 

In this case, member i all instances of class X initialized to 5 constructor generated by the compiler, and member f initialized to 3.12 . The static const j data element is initialized to 42 , and the static constexpr data element is initialized to 9.5 .

Since float and double are not integer or enumerated types, such members must either be constexpr or not static so that the initializer in the class definition is allowed.

Prior to C ++ 11, only static const members of data of an integral or enumeration type could have initializers in the class definition.

+103
Feb 09 '12 at 9:35
source share

Initialization of static member variables other than const int types is not standard C ++ to C ++ 11. The gcc compiler will not warn you about this (and, nevertheless, create useful code) if you do not specify the -pedantic . Then you should get an error similar to:

 const.cpp:3:36: error: floating-point literal cannot appear in a constant-expression const.cpp:3:36: warning: ISO C++ forbids initialization of member constant 'tolerance' of non-integral type 'const float' [-pedantic] 

The reason for this is that the C ++ standard does not indicate how the floating point function should be performed and left to the processor. To get around this and other limitations, constexpr was introduced.

+41
Feb 08 2018-12-12T00:
source share

Yes. Just add the constexpr keyword as the error says.

+9
Feb 04 '12 at 15:30
source share

If you need only one method, you can declare it locally static:

 struct equal_vec { bool operator() (const Vector3D& a, const Vector3D& b) const { static const float tolerance = 0.001f; Vector3D dist = b - a; return ( dist.length2() <= tolerance ); } }; 
+1
Feb 14 '12 at 23:28
source share

I ran into real problems with this because I need the same code to compile with different versions of g ++ (GNU C ++ compiler). So I had to use a macro to see which version of the compiler was used, and then act accordingly:

 #if __GNUC__ > 5 #define GNU_CONST_STATIC_FLOAT_DECLARATION constexpr #else #define GNU_CONST_STATIC_FLOAT_DECLARATION const #endif GNU_CONST_STATIC_FLOAT_DECLARATION static double yugeNum=5.0; 

This will use 'const' for everything up to g ++ version 6.0.0, and then use 'constexpr' for g ++ version 6.0.0 and higher. This is an assumption about the version where the change occurs, because, frankly, I did not notice this before g ++ 6.2.1. To do this correctly, you may have to look at the lower version and g ++ patch number, so see

https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html

for information on available macros.

With gnu, you can also use 'const' everywhere and then compile with the -fpermissive flag, but this gives warnings, and I like when my things compile cleanly.

Incredible because it is specific to gnu compilers, but I suspect you could do something similar with other compilers.

+1
Oct 26 '16 at 22:02
source share

Well, not quite a direct answer, but any specific reason not to use a macro?

 #define tolerance 0.001 struct equal_vec { bool operator() (const Vector3D& a, const Vector3D& b) const { Vector3D dist = b - a; return ( dist.length2() <= tolerance ); } }; 

Not really good C # practice, but IMHO is completely legal in C ++.

-2
Feb 15 2018-12-12T00:
source share



All Articles