Используйте `size_t` как тип счетчика

Уместно ли использовать size_t вместо int или unsigned в качестве типа счетчика?

Следующий код взят из C++ Primer.

size_t count_calls()
{
    static size_t ctr = 0;
    return ++ctr;
}

int main()
{
    for (size_t i = 0; i != 10; ++i)
        cout << count_calls() << endl;
    return 0;
}

Я знаю, что size_t — хороший выбор для размера, индексации массива, но как насчет простого счетчика? (как в функции count_calls.) Есть ли разница?


person pallxk    schedule 23.09.2014    source источник
comment
en.cppreference.com/w/cpp/types/size_t   -  person Decipher    schedule 23.09.2014
comment
возможный дубликат unsigned int vs. size_t   -  person milgner    schedule 23.09.2014
comment
Изменить: неуместная идея для этой проблемы. В C++11 используйте auto и итераторы, чтобы избежать принятия этого решения во многих случаях.   -  person Neil Kirk    schedule 23.09.2014
comment
Связанный с этим вопрос: stackoverflow.com/questions/24226483/   -  person manlio    schedule 23.09.2014
comment
@NeilKirk в этом случае auto будет иметь подписанный тип. не то, что хочет пользователь...   -  person Alexander Oh    schedule 23.09.2014
comment
@Алекс Ты прав! Здесь это не очень хорошее решение. Я думал об итерации структуры данных.   -  person Neil Kirk    schedule 23.09.2014


Ответы (1)


size_t — это тип, подходящий для подсчета элементов в массиве и, следовательно, в любом контейнере на основе массива. Однако size_t концептуально недостаточно для подсчета элементов в контейнере, не основанном на массиве. (Например, не гарантируется, что size_t будет достаточно широким для подсчета элементов std::list.) По этой причине в общем случае нецелесообразно использовать size_t в качестве универсального типа счетчика. И очевидным примером может служить модель сегментированной памяти, при которой size_t может легко оказаться относительно узким по сравнению с емкостью самой платформы.

Если вы действительно хотите найти общий тип, который достаточно широк для большинства реальных случаев, это будет uintptr_t возможно. И опять же, выбор в данном случае основан на том, что uintptr_t должно быть достаточно широким, чтобы посчитать все, что может поместиться в памяти. Однако по понятным причинам он может оказаться слишком маленьким, чтобы считать что-то более обширное.

Я бы также добавил, что использование таких универсальных типов, как size_t и unitptr_t, в качестве счетчиков в коде, специфичном для приложения, может считаться сомнительной практикой программирования, поскольку они не передают никакой семантики, специфичной для приложения. Они больше ориентированы на память, чем на общий счетчик.

person AnT    schedule 23.09.2014