【问题标题】:How do I implement array::max_size()?如何实现 array::max_size()?
【发布时间】:2011-07-01 09:29:04
【问题描述】:

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


嗯,来自当前 g++ 的 std::array 和来自 max_size()boost::array 返回 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
}

【问题讨论】:

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


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      我同意这里的草稿有些欠缺。

      不清楚container这里是否引用:

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

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

      查看basic_string::append,描述状态:

      抛出:length_error 如果size() + n &gt; max_size()

      有了这句话,我认为该标准为通用算法的规范奠定了基础检查max_size

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

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

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

      【讨论】:

      • max_size 的要求是在所有容器使用分配器获取其内存时编写的。那么 max_size() 是“可以合理地传递给 allocator::allocate() 的最大值”。没有具体说明“合理”是什么意思。 :-)
      【解决方案3】:

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

      如果不是n,那么narray&lt;T, n&gt; 中代表什么?

      【讨论】:

        【解决方案4】:

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

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

        【讨论】:

        • 我知道这不是标准,但sgi.com/tech/stl/Container.html 声称“对于固定大小的容器,size() == max_size()。” std::array的定义并没有说max_size()具体返回什么,但大概和size()是一样的。
        • @Jeremiah Willcock:归结为 SGI 文档或标准是否更权威的问题。至少对我来说,这个选择似乎很明显。
        • 如果array&lt;T, N&gt;::max_size 必须返回array&lt;T, largest_possible_n&gt;::max_size,那么根据这个逻辑vector&lt;EnormousObject&gt;::max_size 是否必须与vector&lt;char&gt;::max_size 相同?或者,我知道array&lt;int, 10&gt;::max_size 类似于 1,000,000,000 对我有什么用处?
        • @UncleBens:是的,max_size 几乎没用。 array 更是如此,因为这些要求从未针对固定大小的容器量身定制。也许要求应该改变,但我怀疑是否有人足够关心打扰。
        • 但这仍然只是解释的问题。说array&lt;T, N&gt; 的“最大可能”大小是N 是最有意义的。 N 是类型的一部分,如果它有不同的值,那么我们会有不同的数组类型吗? (并且实施似乎同意这一点。)
        【解决方案5】:

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

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

        如果您为 STL 容器编写了分配器类,则可以像这样实现 max_size() 函数来提供准确的对象计数,而不是使用 std::numeric_limits&lt;size_type&gt;::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
        

        【讨论】:

          猜你喜欢
          • 2021-11-16
          • 2018-06-29
          • 2011-01-30
          • 2019-09-03
          • 2020-03-01
          • 2010-10-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多