Как мне реализовать array :: max_size ()? - PullRequest
4 голосов
/ 21 февраля 2011

Я строю свой собственный array<T, n> шаблон класса для развлечения и образования.В проекте стандарта C ++ 0x функция-член max_size() для всех контейнеров указывается как distance(begin(), end()) "для максимально возможного контейнера".Как мне реализовать эту функцию-член для массивов?Я просто возвращаю std::numeric_limits<std::size_t>::max(), или результат должен зависеть от типа элемента?


Хмм, оба std::array от текущего g ++ и boost::array return n от 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
}

Ответы [ 5 ]

6 голосов
/ 21 февраля 2011

Если ваш массив фиксированного размера, просто верните размер (n в вашем примере), так как это также максимальный размер.

4 голосов
/ 21 февраля 2011

Я согласен с тем, что здесь черновой вариант не хватает.

Неясно, ссылается ли container здесь:

  • любой контейнер
  • любой контейнер этогоfamily
  • любой контейнер данного экземпляра этого семейства

В отличие от @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 будет логически применимо к распределителям фиксированного размера (и особенностековые распределители как написано Говардом Хinnant).

4 голосов
/ 21 февраля 2011

Это должно быть n, поскольку массив подразумевает фиксированный размер.И здесь фиксированный размер n.

Если это что-то отличное от n, то что означает n в array<T, n>?

3 голосов
/ 21 февраля 2011

Да, я думаю, что это обычно должно зависеть от размера элемента, поэтому у вас обычно будет что-то вроде: std::numeric_limits<std::size_t>::max()/sizeof(T). В противном случае вы даете размер, который обычно будет на больше , чем на самом деле возможно.

Редактировать: Исходя из таблицы 93, я не согласен с Навазом и Иеремией Уилкоком. max_size четко описывается как размер for the largest possible container, , а не наибольший размер, до которого может расширяться конкретный контейнер.

0 голосов
/ 21 сентября 2017

В документации для max_size говорится, что функция должна возвращать "максимально теоретически возможное значение n, для которого вызов allocate (n, 0) может быть успешным", где n - количество объектов.

Контейнеры STL (например, - std :: vector, std :: map или std :: list) используют max_size для вычисления размера контейнера с точки зрения количества объектов, а не количества байтов.Поэтому max_size () не должна возвращать количество байтов, доступных в операционной системе, а использовать количество доступных байтов для вычисления количества объектов, которые может содержать распределитель.

Если вы написали класс распределителя для STLконтейнеры, вы можете реализовать функцию 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...