30

我想在一个类中定义一个常量,它的值是最大可能的 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 的所有成员,特化应以可用作整数常量表达式的方式定义这些值。

    这是否意味着我应该能够在我的场景中使用它并且它不与错误消息相矛盾?

谢谢你。

4

5 回答 5

17

好像有点瑕疵。。。

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

于 2010-04-29T15:16:21.287 回答
16

虽然当前标准在这里缺乏支持,但对于整数类型Boost.IntegerTraits为您提供了编译时间常量const_minconst_max.

问题来自§9.4.2/4

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

请注意,它添加了:

如果在程序中使用该成员,则该成员仍应在名称空间范围内定义,并且名称空间范围定义不应包含初始值设定项。

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

于 2010-04-29T15:26:26.780 回答
14

你要:

#include <limits>

struct A {
static const int ERROR_VALUE;
}; 

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

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

于 2010-04-29T15:13:18.900 回答
4

这并不矛盾,因为maxis not defined static const。它只是一个静态成员函数。函数不能是 const,静态成员函数也不能在最右边附加 const。

在 double 版本的限制中还有一个double max(),在 C++03 中它不会说static double const max = .... 所以要保持一致,max()是一个适用于所有版本的限制模板的功能。

现在,众所周知,max()不能像那样使用是很糟糕的,C++0x 已经通过将其设为constexpr函数来解决它,允许您建议的用法。

于 2010-04-29T15:16:38.467 回答
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));
}

希望这可以帮到你..

于 2010-04-29T16:36:06.537 回答