如何实现 array::max_size()?

发布于 2024-10-18 13:29:00 字数 679 浏览 5 评论 0原文

我正在构建自己的 array 类模板以获取乐趣和教育。 C++0x 标准草案将所有容器的成员函数 max_size() 指定为 distance(begin(), end())“对于最大可能的容器”。如何为数组实现这个成员函数?我是否只是返回 std::numeric_limits::max(),或者结果应该取决于元素类型?


嗯,当前 g++ 中的 std::array 和 boost::array 都从 max_size() 中返回 n:

#include <array>
#include <boost/array.hpp>
#include <iostream>

int main()
{
    std::array<int, 11> foo;
    std::cout << foo.max_size() << std::endl;   // prints 11

    boost::array<int, 11> bar;
    std::cout << bar.max_size() << std::endl;   // prints 11
}

I am building my own array<T, n> class template for fun and education. The C++0x standard draft specifies a member function max_size() for all containers as distance(begin(), end()) "for the largest possible container". How do I implement this member function for arrays? Do I simply return std::numeric_limits<std::size_t>::max(), or should the result depend on the element type?


Hmm, both std::array from current g++ and boost::array return n from max_size():

#include <array>
#include <boost/array.hpp>
#include <iostream>

int main()
{
    std::array<int, 11> foo;
    std::cout << foo.max_size() << std::endl;   // prints 11

    boost::array<int, 11> bar;
    std::cout << bar.max_size() << std::endl;   // prints 11
}

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

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

发布评论

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

评论(5

杀お生予夺 2024-10-25 13:29:00

如果您的数组是固定大小的,则只需返回大小(示例中的 n ),因为这也是最大大小。

If your array is fixed-size, just return the size (n in your example), since that is also the maximum size.

叫嚣ゝ 2024-10-25 13:29:00

我同意草案在这里有些欠缺。

目前尚不清楚 container 这里是否引用:

  • 该系列的任何容器
  • 该系列的任何容器
  • 该系列的给定实例的任何容器

与@Jerry不同,我倾向于后一种选择。

查看 basic_string::append,描述如下:

抛出:length_error 如果 size() + n > max_size()

有了这句话,我认为该标准为通用算法的规范奠定了基础,这些算法的行为会根据它们是否在其上运行的Container而有所不同是否可以扩展,可以通过max_size来检查。

因此,Container 逻辑上应该返回其最大长度。

因此,std::size_t std::array::max_size() const { return n; } 是合乎逻辑的选择。

请注意,这个相同的 max_size 定义在逻辑上适用于固定大小的分配器(尤其是 Howard Hinnant 编写的基于堆栈的分配器)。

I agree that the draft is somewhat lacking here.

It is unclear whether container here references:

  • any container
  • any container of this family
  • any container of a given instance of this family

Unlike @Jerry I would lean toward the latter option.

Looking at basic_string::append, the description states:

Throws: length_error if size() + n > max_size()

With this remark, I think that the Standard puts its foot in the door for the specification of generic algorithms whose behavior would differ based on whether or not the Container they are operating on can be expanded or not, which can be checked with max_size.

As such, a Container should logically returns its maximum length.

Therefore, std::size_t std::array<T,n>::max_size() const { return n; } is the logical choice.

Note that this same max_size definition would logically be applicable to fixed-sized allocators (and notably, stack-based allocators as written by Howard Hinnant).

对你而言 2024-10-25 13:29:00

它应该是n,因为数组意味着固定大小。这里的固定大小是n

如果不是 n,那么 narray 中代表什么?

It should be n, as array implies fixed-size. And here the fixed size is n.

If it's anything other than n, then what does n stand for in array<T, n>?

执手闯天涯 2024-10-25 13:29:00

是的,我认为它通常应该取决于元素大小,因此通常会有类似以下内容:std::numeric_limits::max()/sizeof(T)。否则,您给出的尺寸通常会比实际可能的尺寸大得多。

编辑:根据表 93,我不同意 Nawaz 和 Jeremiah Willcock 的观点。 max_size 明确描述为可能的最大容器的大小,而不是特定容器可以扩展到的最大大小。

Yes, I think it should normally depend on the element size, so you'd typically have something like: std::numeric_limits<std::size_t>::max()/sizeof(T). Otherwise, you're giving a size that's typically going to be considerably larger than is actually possible.

Edit: Based on table 93, I have to disagree with Nawaz and Jeremiah Willcock. max_size is clearly described as the size for the largest possible container, not the largest size to which a specific container could expand.

昵称有卵用 2024-10-25 13:29:00

max_size 文档表示该函数应返回“理论上 n 的最大可能值,调用 allocate(n, 0) 可以成功,”其中 n 是对象的数量。

STL 容器(例如 - std::vector、std::map 或 std::list)使用 max_size 根据对象计数而不是字节计数来计算容器大小。因此,max_size()不应该返回操作系统上可用的字节数,而是使用可用字节数来计算分配器可以容纳的对象数量。

如果您为 STL 容器编写了一个分配器类,则可以像这样实现 max_size() 函数来提供准确的对象计数,而不是使用 std::numeric_limits::max()std::numeric_limits::max().

size_type max_size() const
{
    const unsigned long long bytesAvailable = GetTotalAvailableMemory();
    const unsigned long long maxPossibleObjects = bytesAvailable / sizeof(value_type);
    return maxPossibleObjects;
}

您可以根据您的操作系统像这些函数一样实现 GetTotalAvailableMemory()。两者都将返回程序进程可以使用的未分配字节数。

#if defined(unix) || defined(__unix__) || defined(__unix)

#include <unistd.h>

unsigned long long GetTotalAvailableMemory()
{
    const long pageCount = sysconf( _SC_PHYS_PAGES );
    const long pageSize = sysconf( _SC_PAGE_SIZE );
    const unsigned long long totalBytes = pageCount * pageSize;
    return totalBytes;
}

#endif

#if defined(_WIN64) || defined(_WIN64)

#include <windows.h>

unsigned long long GetTotalAvailableMemory()
{
    MEMORYSTATUSEX status;
    status.dwLength = sizeof( status );
    GlobalMemoryStatusEx( &status );
    return status.ullAvailVirtual;
}

#endif

The documentation for max_size says the function should return "the maximum theoretically possible value of n, for which the call allocate(n, 0) could succeed," where n is the number of objects.

The STL containers (e.g. - std::vector, std::map, or std::list) use max_size to calculate container size in terms of object count, not byte count. Therefore, max_size() should not return the number of bytes available on the operating system, but use the number of available bytes to calculate the number of objects the allocator can hold.

If you wrote an allocator class for STL containers, you could implement the max_size() function like this to provide an accurate object count instead of over-estimating by using std::numeric_limits<size_type>::max().

size_type max_size() const
{
    const unsigned long long bytesAvailable = GetTotalAvailableMemory();
    const unsigned long long maxPossibleObjects = bytesAvailable / sizeof(value_type);
    return maxPossibleObjects;
}

You can implement the GetTotalAvailableMemory() like these functions depending on your operating system. Either will return the number of unallocated bytes which a program's process may use.

#if defined(unix) || defined(__unix__) || defined(__unix)

#include <unistd.h>

unsigned long long GetTotalAvailableMemory()
{
    const long pageCount = sysconf( _SC_PHYS_PAGES );
    const long pageSize = sysconf( _SC_PAGE_SIZE );
    const unsigned long long totalBytes = pageCount * pageSize;
    return totalBytes;
}

#endif

#if defined(_WIN64) || defined(_WIN64)

#include <windows.h>

unsigned long long GetTotalAvailableMemory()
{
    MEMORYSTATUSEX status;
    status.dwLength = sizeof( status );
    GlobalMemoryStatusEx( &status );
    return status.ullAvailVirtual;
}

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