问题
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.
回答1:
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.
回答2:
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.
回答3:
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.
回答4:
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.
回答5:
- 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..
来源:https://stackoverflow.com/questions/2738435/using-numeric-limitsmax-in-constant-expressions