Как соотносятся все разные типы размеров? - PullRequest
8 голосов
/ 10 марта 2011

В настоящее время у меня есть сценарий, в котором я хочу проверить, будет ли запись данной строки в файловый поток увеличивать размер файла до заданного размера (это используется для ротации файла журнала). Теперь std::ofstream::tellp() возвращает streampos, но std::string::size() возвращает size_t. Эффект в том, что это не работает:

out_stream.tellp() + string.size() < limit

потому что, по-видимому, существует неоднозначная перегрузка operator + для этих типов. Это приводит меня к двум вопросам:

  1. Как я могу устранить вышеуказанную двусмысленность?
  2. Как все различные типы (size_t, streamsize, streampos, streamoff) связаны друг с другом? Когда они могут быть безопасно преобразованы, и каковы возможные подводные камни. Я вообще смущен этими типами. Все, что я знаю, это то, что они зависят от реализации, и что они дают определенные гарантии (например, size_t всегда достаточно велик, чтобы вместить размер объекта larges, который вписывался бы в память на архитектуре, для которой было скомпилировано приложение), но Каковы гарантии, касающиеся совместимости этих типов (см. пример выше или сравнение streamsize с size_t)?

Ответы [ 4 ]

4 голосов
/ 10 марта 2011

Вы должны иметь возможность преобразовать результат из Tellp в std::string::size_type путем приведения.

static_cast<std::string::size_type>(out_stream.tellp()) + string.size() < limit

РЕДАКТИРОВАТЬ: Это безопасно, потому что смещение вашего потока никогда не будет отрицательным ибезопасно конвертируется в беззнаковое значение.

3 голосов
/ 10 марта 2011

Реальный вопрос: какой тип ограничения? Обычный способ Тестирование, если есть еще место, обычно: limit - out_stream.tellp ()> = string.size () Но вы должны убедиться, что лимит имеет тип, из которого out_stream.tellp () можно вычесть.

Теоретически, streampos не конвертируемы и не сравнимы с интегралом тип или что, преобразуется в целочисленный тип, это дает значительный Информация. И для этого требовалось вычитание поддержки или сравнение. иметь значение. На практике я не думаю, что вам нужно слишком беспокоиться о преобразование в цельный тип, существующий и являющийся монотонным (хотя возможно на каком-то экзотическом мейнфрейме ...). Но вы не можете быть уверены, что арифметика с ним будет работать, поэтому я бы предпочел преобразовать его явно к размеру потока (который гарантированно будет знаком со знаком тип). (Независимо от того, как вы подходите к проблеме, вам придется иметь дело с с тем фактом, что string.size () возвращает size_t, который требуется для быть без знака, тогда как размер потока должен быть подписан.)

Что касается вашего второго вопроса: size_t - это typedef для целого типа без знака, достаточно большой, чтобы указать размер любого возможного объекта, streamsize - это typedef для целочисленного типа со знаком, достаточно большой, чтобы указать размер «объекта» в потоке, streamoff - это typedef для целочисленного типа, способного указывать положение байта в файле, и streampos является typedef для fpos, где что-то является типом, который может быть использован для поддержания состояния в случай многобайтового потока. Стандарт предъявляет очень мало требований относительно отношений между ними (и некоторые из немногих, что это делает, математически невозможно чтобы понять), так что вы в значительной степени самостоятельно.

1 голос
/ 10 марта 2011

Я полагаю, что стандарт говорит, что streamsize зависит от реализации, так что тут никакой помощи.Для практического ответа вы можете проверить заголовки, где они typedef ed.

Учитывая, что size_t может быть 4 байта, в то время как ваше приложение может предположительно работать с потоком болеедлиной более 4 ГБ, я полагаю, что вы должны привести к типу известного хорошего размера для взаимодействия для воздухонепроницаемого решения.

Конечно, если вы знаете (возможно, с утверждением времени компиляции), что size_tили streamsize имеет длину 8 байт, вы можете использовать этот тип напрямую.Если у вас есть поток, длина которого не помещается в 8 байтов, у вас есть более серьезные проблемы, чем приведение к нужному типу.

0 голосов
/ 10 марта 2011

Если у вас большие размеры, не лучше длинная без знака лучшее, что вы можете получить. Если этого недостаточно, что еще?

...