I would like to define inside a class a constant which value is the maximum possible int. Something like this:
class A
{
...
static const int ERROR_VALUE = std::numeric_limits<int>::max();
...
}
This declaration fails to compile with the following message:
numeric.cpp:8: error: 'std::numeric_limits::max()' cannot appear in a constant-expression
numeric.cpp:8: error: a function call cannot appear in a constant-expression
I understand why this doesn't work, but two things look weird to me:
It seems to me a natural decision to use the value in constant expressions. Why did the language designers decide to make max() a function thus not allowing this usage?
The spec claims in 18.2.1 that
For all members declared static const in the numeric_limits template, specializations shall define these values in such a way that they are usable as integral constant expressions.
Doesn't it mean that I should be able to use it in my scenario and doesn't it contradict the error message?
Thank you.
While the current standard lacks support here, for integral types Boost.IntegerTraits gives you the compile time constants const_min
and const_max
.
The problem arises from §9.4.2/4:
If a static data member is of const integral or const enumeration type, its declaration in the class definition can specify a constant-initializer which shall be an integral constant expression (5.19). In that case, the member can appear in integral constant expressions.
Note that it adds:
The member shall still be defined in a name- space scope if it is used in the program and the namespace scope definition shall not contain an initializer.
As others already mentioned numeric_limit
s min()
and max()
simply aren't integral constant expressions, i.e. compile time constants.
Looks like a bit of a defect...
In C++0x, numeric_limits
will have everything marked with constexpr
, meaning you will be able to use min()
and max()
as compile-time constants.
You want:
#include <limits>
struct A {
static const int ERROR_VALUE;
};
const int A::ERROR_VALUE = std::numeric_limits<int>::max();
Put the class/struct in a header and the definition in a .cpp file.
It doesn't contradict, because max
is not defined static const
. It's just a static member function. Functions can't be const, and static member functions can't have a const attached at the very right either.
There is also a double max()
in the double version of the limits, and in C++03 it wouldn't work to say static double const max = ...
. So to be consistent, max()
is a function for all versions of the limit template.
Now, it's known that max()
not being able to be used like that is bad, and C++0x already solves it by making it a constexpr
function, allowing your proposed usage.
- I will try to answer you as much as I understood from your question:
1- If you want a static const int in your program to be initialized with a function:
int Data()
{
return rand();
}
class A
{
public :
static const int ee;
};
const int A::ee=Data();
This works on VS 2008
2- If you want to get max and min number for a given data type, then use these definitions
INT_MAX, INT_MIN, LONG_MAX and so on..
3- If however you need to use these wrt template type, then
hard code the templates yourself
template<>
int MaxData()
{
return INT_MAX;
}
and
template<>
long MaxData()
{
return LONG_MAX ;
}
and call them like this
int y=MaxData<int>();
4- and if you are only dealing with binary represented types only, then use this:
template <class T>
T MaxData(){
return ~(1<<((sizeof(T)*8)-1));
}
and this
template <class T>
T MinData(){
return (1<<((sizeof(T)*8)-1));
}
Hope this can help you..