我如何实现array :: max_size()?

时间:2011-02-21 16:10:04

标签: c++ arrays stl c++11 aggregate

我正在建立自己的array<T, n>课程模板,用于娱乐和教育。 C ++ 0x标准草案为所有容器指定成员函数max_size(),作为distance(begin(), end())“,用于最大可能的容器”。如何为数组实现此成员函数?我只是返回std::numeric_limits<std::size_t>::max(),还是结果取决于元素类型?


嗯,来自当前g ++的std::array和来自boost::array的{​​{1}}都返回n

max_size()

5 个答案:

答案 0 :(得分:6)

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

答案 1 :(得分:4)

它应该是n,因为数组意味着固定大小。此处固定大小为n

如果它不是n,那么narray<T, n>代表什么?

答案 2 :(得分:4)

我同意草案在这里有点缺乏。

目前还不清楚container是否引用:

  • 任何容器
  • 这个家庭的任何容器
  • 此系列的给定实例的任何容器

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

查看basic_string::append,说明中指出:

  

如果length_error

,则抛出size() + n > max_size()

有了这样的说法,我认为标准为通用算法的规范提供了基础,通用算法的行为会根据它们正在运行的Container是否可以扩展而有所不同,可以使用max_size进行检查。

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

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

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

答案 3 :(得分:3)

是的,我认为它通常应该取决于元素大小,所以你通常会有类似的东西:std::numeric_limits<std::size_t>::max()/sizeof(T)。否则,你给出的尺寸通常比实际可能的更大

编辑:根据表93,我不得不同意Nawaz和Jeremiah Willcock。 max_size清楚地描述为大小for the largest possible container不是特定容器可以扩展的最大大小。

答案 4 :(得分:0)

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

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

如果你为STL容器编写了一个allocator类,你可以像这样实现max_size()函数来提供准确的对象计数,而不是使用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;
}

您可以像这些函数一样实现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