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

发布于 2024-08-30 18:07:39 字数 643 浏览 10 评论 0原文

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

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 的所有成员,特化应以可用作整型常量表达式的方式定义这些值。

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

谢谢。

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:

  1. 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?

  2. 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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

小草泠泠 2024-09-06 18:07:39

虽然当前标准缺乏对整数类型的支持 Boost.IntegerTraits 为您提供编译时间常数 const_minconst_max

问题源自§9.4.2/4

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

请注意,它添加了:

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

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

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_limits min() and max() simply aren't integral constant expressions, i.e. compile time constants.

神经暖 2024-09-06 18:07:39

看起来有点缺陷...

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

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.

尤怨 2024-09-06 18:07:39

您想要:

#include <limits>

struct A {
static const int ERROR_VALUE;
}; 

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

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

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.

安静 2024-09-06 18:07:39

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

在双精度版本的限制中还有一个 double max(),在 C++03 中,不能说 static double const max = ... >。因此为了保持一致,max() 是适用于所有版本的限制模板的函数。

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

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.

情归归情 2024-09-06 18:07:39
  • 我将尽力回答您从您的问题中了解到的内容:

1-如果您希望使用函数初始化程序中的 static 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));
}

这可以帮助您..

  • 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..

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文