我正在建立自己的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()
答案 0 :(得分:6)
如果您的数组是固定大小的,只需返回大小(示例中为n
),因为这也是最大大小。
答案 1 :(得分:4)
它应该是n
,因为数组意味着固定大小。此处固定大小为n
。
如果它不是n
,那么n
中array<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