In PHP and C# the constants can be initialized as they are declared:
class Calendar3
{
const int value1 = 12;
const double value2 = 0.001;
}
I have the following C++ declaration of a functor which is used with another class to compare two math 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 outputs an error message:
error: ‘constexpr’ needed for in-class initialization of static data member ‘tolerance’ of non-integral type
I know I can define and initialize this static const
member outside of the class definition. Also, a non-static constant data member can be initialized in the initializer list of a constructor.
But is there any way to initialize a constant within class declaration just like it is possible in PHP or C#?
Update
I used static
keyword just because it was possible to initialize such constants within the class declaration in g++. I just need a way to initialize a constant in a class declaration no matter if it declared as static
or not.
Well, not exactly a direct answer, but any specific reason not to use a macro?
Not exactly good C# practice, but IMHO perfectly legit in C++.
If you only need it in the one method you can declare it locally static:
In C++11, non-
static
data members,static constexpr
data members, andstatic const
data members of integral or enumeration type may be initialized in the class declaration. e.g.In this case, the
i
member of all instances of classX
is initialized to5
by the compiler-generated constructor, and thef
member is initialized to3.12
. Thestatic const
data memberj
is initialized to42
, and thestatic constexpr
data memberg
is initialized to9.5
.Since
float
anddouble
are not of integral or enumeration type, such members must either beconstexpr
, or non-static
in order for the initializer in the class definition to be permitted.Prior to C++11, only
static const
data members of integral or enumeration type could have initializers in the class definition.Yes. Just add the
constexpr
keyword as the error says.Initializing static member variables other than const int types is not standard C++ prior C++11. The gcc compiler will not warn you about this (and produce useful code nonetheless) unless you specify the
-pedantic
option. You then should get an error similiar to:The reason for this is that the C++ standard does not specifiy how floating point should be implemented and is left to the processor. To get around this and other limitations
constexpr
was introduced.I ran into real problems with this, because I need the same code to compile with differing versions of g++ (the GNU C++ compiler). So I had to use a macro to see which version of the compiler was being used, and then act accordingly, like so
This will use 'const' for everything before g++ version 6.0.0 and then use 'constexpr' for g++ version 6.0.0 and above. That's a guess at the version where the change takes place, because frankly I didn't notice this until g++ version 6.2.1. To do it right you may have to look at the minor version and patch number of g++, so see
https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html
for the details on the available macros.
With gnu, you could also stick with using 'const' everywhere and then compile with the
-fpermissive
flag, but that gives warnings and I like my stuff to compile cleanly.Not great, because it's specific to gnu compilers, butI suspect you could do similar with other compilers.