Где я могу найти определение size_type для векторов в C ++ STL? - PullRequest
5 голосов
/ 22 октября 2008

Кажется безопасным привести результат функции size() моего вектора к unsigned int. Как я могу сказать наверняка, хотя? В моей документации неясно, как определяется size_type.

Ответы [ 7 ]

11 голосов
/ 22 октября 2008

Не предполагайте тип размера контейнера (или что-либо еще напечатанное внутри).

Сегодня

На данный момент лучшим решением является использование:

std::vector<T>::size_type

Где Т - твой тип. Например:

std::vector<std::string>::size_type i ;
std::vector<int>::size_type j ;
std::vector<std::vector<double> >::size_type k ;

(Использование typedef может помочь улучшить чтение)

То же самое относится к итераторам и всем остальным типам "внутри" контейнеров STL.

После C ++ 0x?

Когда компилятор сможет найти тип переменной, вы сможете использовать ключевое слово auto. Например:

void doSomething(const std::vector<double> & p_aData)
{
    std::vector<double>::size_type i = p_aData.size() ; // Old/Current way

    auto j = p_aData.size() ;    // New C++0x way, definition
    decltype(p_aData.size()) k;  // New C++0x way, declaration
}

Редактировать: вопрос от JF

Что если ему нужно передать размер контейнера в какой-то существующий код, который использует, скажем, целое число без знака? - JF

Эта проблема характерна для использования STL: вы не можете сделать это без некоторой работы.

Первым решением является разработка кода, который всегда будет использовать тип STL. Например:

typedef std::vector<int>::size_type VIntSize ;

VIntSize getIndexOfSomeItem(const std::vector<int> p_aInt)
{
   return /* the found value, or some kind of std::npos */
}

Второе - сделать преобразование самостоятельно, используя static_cast, используя функцию, которая будет утверждать, если значение выходит за границы целевого типа (иногда я вижу код, использующий "char", потому что " вы знаете, индекс никогда не превысит 256"[цитирую по памяти]).

Я полагаю, что это может быть полный вопрос сам по себе.

4 голосов
/ 22 октября 2008

Согласно стандарту, вы не можете быть уверены . Точный тип зависит от вашей машины. Вы можете посмотреть определение в реализациях заголовков вашего компилятора.

3 голосов
/ 22 октября 2008

Я не могу себе представить, что это не будет безопасно в 32-битной системе, но 64-битная может быть проблемой (поскольку целые числа остаются 32-битными). На всякий случай, почему бы просто не объявить вашу переменную вектором :: size_type вместо unsigned int?

1 голос
/ 23 октября 2008

Стандарт C ++ гласит только, что size_t находится в , что помещает идентификаторы в . Моя копия Harbison & Steele помещает минимальные и максимальные значения для size_t в . Это должно дать вам представление о том, насколько большой должна быть переменная получателя для вашей платформы.

Лучше всего придерживаться целочисленных типов, которые достаточно велики, чтобы держать указатель на вашей платформе. В C99 это были бы intptr_t и uintptr_t , также официально находящиеся в .

0 голосов
/ 22 октября 2008

Всегда должно быть безопасно привести его к size_t. unsigned int недостаточно в большинстве 64-битных систем, и даже unsigned long недостаточно в Windows (которая использует модель LLP64 вместо модели LP64, используемой большинством Unix-подобных систем).

0 голосов
/ 22 октября 2008

Я не уверен, насколько хорошо это будет работать, потому что я просто думаю над головой, но утверждение времени компиляции (например, BOOST_STATIC_ASSERT() или см. Способы ASSERT выражений во время сборки в C ) может помочь. Что-то вроде:

BOOST_STATIC_ASSERT( sizeof( unsigned int) >= sizeof( size_type));
0 голосов
/ 22 октября 2008

До тех пор, пока вы уверены, что целое число без знака в вашей системе будет достаточно большим, чтобы вместить количество элементов, которое у вас будет в векторе, вы должны быть в безопасности; -)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...