在常量表达式中使用numeric_limits :: max()

时间:2010-04-29 15:07:51

标签: c++ std constexpr numeric-limits

我想在类中定义一个常量,该值是最大可能的int。像这样:

class A
{
    ...
    static const int ERROR_VALUE = std::numeric_limits<int>::max();
    ...
}

此声明无法使用以下消息进行编译:

  

numeric.cpp:8:错误:'std :: numeric_limits :: max()'不能出现在常量表达式中   numeric.cpp:8:错误:函数调用不能出现在常量表达式

我理解为什么这不起作用,但有两件事对我来说很奇怪:

  1. 在我看来,在常量表达式中使用该值是一个自然的决定。为什么语言设计者决定使 max()成为一个函数,从而不允许这种用法?

  2. 规范在18.2.1中声称

      

    对于在numeric_limits模板中声明为static const的所有成员,特化应以这样的方式定义这些值,使它们可用作整型常量表达式。

    这不是说我应该能够在我的场景中使用它并且它不会与错误消息相矛盾吗?

  3. 谢谢。

5 个答案:

答案 0 :(得分:16)

看起来有点缺陷......

在C ++ 0x中,numeric_limits将包含标有constexpr的所有内容,这意味着您将能够使用min()max()作为编译时常量。< / p>

答案 1 :(得分:16)

虽然目前的标准缺乏支持,但对于整数类型Boost.IntegerTraits,您可以获得编译时常量const_minconst_max

问题来自§9.4.2/ 4

  

如果静态数据成员是const integer或const枚举类型,则它在类定义中的声明可以指定一个常量初始化器,它应该是一个整型常量表达式(5.19)。在这种情况下,成员可以出现在整数常量表达式中。

请注意,它添加:

  

如果在程序中使用该成员,并且名称空间作用域定义不包含初始化程序,则仍应在名称空间作用域中定义该成员。

正如其他人已经提到的那样numeric_limit s min()max()根本不是整数常量表达式,即编译时常数。

答案 2 :(得分:13)

你想:

#include <limits>

struct A {
static const int ERROR_VALUE;
}; 

const int A::ERROR_VALUE = std::numeric_limits<int>::max();

将类/结构放在标题中,将定义放在.cpp文件中。

答案 3 :(得分:4)

它并不矛盾,因为max未定义static const。它只是一个静态成员函数。函数不能是const,静态成员函数也不能在最右边附加一个const。

在限制版的双重版本中还有double max(),在C ++ 03中,static double const max = ...无效。因此,为了保持一致,max()是限制模板的所有版本的函数。

现在,已知max()无法像这样使用是不好的,C ++ 0x已经通过使其成为constexpr函数来解决它,允许您的建议使用。

答案 4 :(得分:2)

  • 我会尽力回答你的问题:

1-如果您希望使用函数初始化程序中的静态const int:

int Data()
{
 return rand();
}

class A
{
public :
    static const int ee;
};
const int A::ee=Data();

适用于VS 2008

2-如果要获取给定数据类型的最大值和最小值,请使用这些定义 INT_MAX,INT_MIN,LONG_MAX等......

3-如果您需要使用这些wrt模板类型,那么 自己硬编码模板

template<>
int MaxData()
{
 return INT_MAX;
}

template<>
long MaxData()
{
 return LONG_MAX ;
}

并像这样打电话给他们

int y=MaxData<int>();

4-如果你只处理二进制表示的类型,那么使用:

template <class T>
T MaxData(){
    return ~(1<<((sizeof(T)*8)-1));
}

和这个

template <class T>
T MinData(){
    return (1<<((sizeof(T)*8)-1));
}

希望这可以帮助你..