Почему string::compare
возвращает int
вместо меньшего типа, например short
или char
? Насколько я понимаю, этот метод возвращает только -1, 0 или 1.
Вторая часть, если бы я должен был разработать метод сравнения, который сравнивает два объекта типа, Foo
и я хотел бы вернуть только -1, 0 или 1, использовал бы short
или char
вообще был бы хорошей идеей?
РЕДАКТИРОВАТЬ: меня исправили, string::compare
не возвращает -1, 0 или 1, фактически возвращает значение> 0, <0 или 0. Спасибо, что держали меня в очереди, ребята.
Похоже, ответ примерно такой: нет причин возвращать тип меньшего, чем, int
потому что возвращаемые значения - это «rvalues», а эти «rvalue» не выигрывают от того, что они меньше типа int (4 байта). Кроме того, многие люди указали, что регистры большинства систем, вероятно, в int
любом случае будут иметь размер , поскольку эти регистры будут заполнены независимо от того, даете ли вы им значение 1, 2 или 4 байта, нет реального преимущества в возврате меньшее значение.
РЕДАКТИРОВАТЬ 2: На самом деле похоже, что при использовании меньших типов данных, таких как выравнивание, маскирование и т. Д., Могут возникнуть дополнительные накладные расходы на обработку. По общему мнению, меньшие типы данных существуют для экономии памяти при работе с большим количеством данных, как в случай массива.
Узнал кое-что сегодня, еще раз спасибо, ребята!
string::compare()
вы ссылаетесь, четко указано, что возвращаемое значение <0, 0 и> 0, а не -1, 0 и 1.short
илиchar
вместоint
? Большинство архитектур собираются хранить возвращаемое значение функции в регистре, и в регистрint
будет помещаться an так же хорошо, какshort
илиchar
. А использованиеchar
числовых типов - всегда плохая идея, особенно когда вам нужно гарантировать правильную обработку подписанных значений.char
было бы плохой идеей, поскольку проверка кода для возвращаемого значения, если оно меньше нуля, не удастся на платформах, где нетchar
знака.Ответы:
Во-первых, спецификация заключается в том, что он вернет значение меньше, равно или больше
0
, не обязательно-1
или1
. Во-вторых, возвращаемые значения - это r-значения, подлежащие полному продвижению, поэтому возвращать что-то меньшее нет смысла.В C ++ (как и в C) каждое выражение является либо rvalue, либо lvalue. Исторически эти термины относятся к тому факту, что lvalue появляются слева от присваивания, тогда как as rvalues могут появляться только справа. Сегодня простое приближение для неклассовых типов состоит в том, что lvalue имеет адрес в памяти, а rvalue - нет. Таким образом, вы не можете взять адрес rvalue, а cv-квалификаторы (условие «доступ») не применяются. В терминах C ++ rvalue, не имеющий типа класса, является чистым значением, а не объектом. Возвращаемое значение функции - rvalue, если оно не имеет ссылочного типа. (Неклассовые типы, которые помещаются в регистр, почти всегда будут возвращаться, например, в регистре, а не в памяти.)
Для типов классов проблемы немного сложнее из-за того, что вы можете вызывать функции-члены по rvalue. Это означает, что rvalues фактически должны иметь адреса для
this
указателя и могут быть квалифицированы cv, поскольку cv-квалификация играет роль в разрешении перегрузки. Наконец, C ++ 11 вводит несколько новых различий для поддержки ссылок rvalue; они также в основном применимы к типам классов.Под интегральным продвижением понимается тот факт, что когда целочисленные типы, меньшие чем an
int
, используются в качестве r-значений в выражении, в большинстве контекстов они будут повышены доint
. Таким образом, даже еслиshort a, b;
в выражении объявлена переменнаяa + b
, обаa
иb
повышаютсяint
до того, как произойдет добавление. Точно так же, если я пишуa < 0
, сравнение выполняется по значениюa
, преобразованному вint
. На практике очень мало случаев, когда это имеет значение, по крайней мере, на машинах с дополнением до 2, где целочисленная арифметика оборачивается (т.е. все, кроме очень немногих экзотических вещей, сегодня - я думаю, что мэйнфреймы Unisys являются единственными оставшимися исключениями). Тем не менее, даже на более распространенных машинах:должен давать разные результаты: первый эквивалент
sizeof( short )
, второйsizeof( int )
(из-за целостного продвижения).Эти две проблемы формально ортогональны; rvalues и lvalues не имеют ничего общего с интегральным продвижением. За исключением ... интегральное продвижение применяется только к rvalue, и в большинстве (но не во всех) случаях, когда вы использовали бы rvalue, результатом было бы полное продвижение. По этой причине действительно нет причин возвращать числовое значение в чем-то меньшем, чем
int
. Есть даже очень веская причина не возвращать его как символьный тип. Например<<
, перегруженные операторы часто ведут себя по-разному для типов символов, поэтому вы хотите возвращать символы только как типы символов. (Вы можете сравнить разницу:Разница в том, что во втором случае добавление вызвало интегральное продвижение, что приводит
<<
к выбору другой перегрузки .источник
return values are rvalues, subject to integral promotion
в своем ответе.signed char
? Будет ли он вести себя так же, как подписанныйchar
, или это будет другой тип?Он намеренно не возвращает -1, 0 или 1.
Он позволяет (обратите внимание, что это не для строк, но в равной степени относится к строкам)
что намного менее громоздко, чем:
что вы должны будете сделать [или что-то в этом роде], если вам нужно вернуть -1, 0 или 1.
И это работает и для более сложных типов:
В случае строки мы можем сделать это:
источник
compare
функции есть проблемы с переполнением, которые (к счастью) не применяются одинаково, если она занимаетchar*
иchar
меньше чемint
. Например, if*a
isMAX_INT
and*b
is-1
then*a - *b
is UB, но если реализация решит определить свое поведение, результат почти наверняка будет отрицательным.length()
возвращает asize_t
, которое может быть больше, чемint
…int обычно (имеется в виду на большинстве современных аппаратных средств) целое число того же размера, что и системная шина и / или регистры процессора, что называется машинным словом. Поэтому int обычно передается быстрее, чем типы меньшего размера, потому что он не требует выравнивания, маскирования и других операций.
Меньшие типы существуют в основном для оптимизации использования ОЗУ для массивов и структур. В большинстве случаев они жертвуют несколькими циклами ЦП (в форме операций выравнивания) для лучшего использования ОЗУ.
Если вам не нужно, чтобы возвращаемое значение было числом со знаком или без знака с размером centain (char, short…), вам лучше использовать int, поэтому стандартная библиотека делает это.
источник
Это C-ism.
Когда C требовал
compare
функций -типа, они всегда возвращалиint
. C ++ просто продвинул это вперед (к сожалению).Однако, на практике, это,
int
вероятно, самый быстрый способ, так как обычно это размер регистров используемой системы. (Умышленно расплывчато.)источник
short
иchar
может налагать штрафы на производительность, например,255+7
имеет другое значение для achar
иint
поэтому правильная реализация не может обязательно просто хранить a,char
гдеint
может идти, не заботясь о передаче его семантики. Компиляторы не обязательно оптимизируют создаваемую этим неэффективность.На самом деле метод не возвращает целое число в наборе
{ -1, 0, 1 }
; фактически это может быть любое целое значение.Зачем? Основная причина, по которой я могу думать, заключается в том, что
int
это должно быть значение «естественного размера» для архитектуры; операции со значениями такого размера обычно выполняются как минимум так же быстро (а во многих случаях и быстрее), чем операции с меньшими или большими значениями. Таким образом, это случай, когда реализации достаточно провисания для использования того, что является самым быстрым.источник
Было бы неплохо. Лучшим способом было бы вернуть bool (если вы хотите сравнить только при равенстве) или enum (для получения дополнительной информации):
источник
Предположим, некоторые люди меняют код с C на C ++. Решили заменить
strcmp
наstring::compare
.Так как
strcmp
возвращаетсяint
,string::compare
вернуть легчеint
, в подарок.источник
Вероятно, чтобы заставить его работать больше, чем у
strcmp
которого также есть этот набор возвращаемых значений . Если бы вы хотели портировать код, вероятно, было бы более интуитивно понятно иметь замены, которые раскалываются как можно ближе.Кроме того, возвращаемое значение не просто
-1
,0
или1
но<0
,0
или>0
.Кроме того, как уже упоминалось, поскольку возврат подлежит комплексному продвижению , нет смысла уменьшать его.
источник
потому что логическое возвращаемое значение может быть только двумя возможными значениями (истина, ложь), а функция сравнения может возвращать три возможных значения (меньше, равно, больше).
Обновить
Хотя, безусловно, можно вернуть короткое значение со знаком , если вы действительно хотите реализовать свою собственную функцию сравнения, вы можете вернуть полубайт или значение структуры с двумя логическими значениями.
источник
short
и вchar
качестве альтернативыint
.