Что делать с size_t и std :: size_t?

Только что прочитав:

Имеет ли смысл std :: size_t в C ++?

Я понимаю, что использование ::size_t не соответствует стандартам (хотя и поддерживается моим компилятором), когда вы #include <cstddef>. Я хочу соответствовать стандарту, но не хочу добавлять std:: ко всем своим size_t. Итак, каков более привычный / популярный способ справиться с этим:

  • написать using std::size_t;?
  • включить <stddef.h>?
  • просто полагаться на поддержку компилятора?
  • что-то другое?

person einpoklum    schedule 14.03.2017    source источник
comment
Мне этот вопрос интересен, хотя, как сказали авторы CV, сказали, он в первую очередь основан на мнении. Возможно, спросите, какой способ наименее навязчивый, но соответствующий стандартам?   -  person Tas    schedule 15.03.2017
comment
@Tas: Я спросил, что люди используют больше всего, так что это не основано на мнении. Меня не волнует, что лучше, это все равно придирки ... Я просто хочу следовать за стадом.   -  person einpoklum    schedule 15.03.2017
comment
И как по набору ответов определить, что люди используют больше всего?   -  person juanchopanza    schedule 15.03.2017
comment
@juanchopanza: Одного ответа должно хватить от того, кто был рядом и видел достаточно кода, чтобы оценить, что является общей практикой. Оценка, основанная на эмпирических наблюдениях! = Мнение. Хотя я признаю, что проголосовавший за это ответ не совсем так.   -  person einpoklum    schedule 15.03.2017
comment
Учитывая, сколько кода один человек может просмотреть за свою жизнь, любой явно авторитетный ответ с большой вероятностью будет мнением.   -  person juanchopanza    schedule 15.03.2017
comment
Практически для всего кода, который использует size_t, лучше использовать int. Но и комитеты C, и C ++ потащили нас по этому пути.   -  person Malcolm McLean    schedule 15.03.2017
comment
@MalcolmMcLean Нам было бы совсем не лучше. size_t имеет семантическое значение и определяется в зависимости от платформы. Также использование int вместо size_t не имеет смысла ни в одном случае. Когда вы используете size_t в ситуации, когда подписанный int имеет смысл, что-то не так.   -  person    schedule 15.03.2017
comment
Мнение @MalcolmMcLean не разделяется подавляющим большинством программистов на C и C ++.   -  person Keith Thompson    schedule 15.03.2017
comment
Требуется использование size_t для индексной переменной, а также недопустимое имя. Последствия изменения sizeof () просто не были продуманы.   -  person Malcolm McLean    schedule 15.03.2017
comment
@MalcolmMcLean: Использование size_t в качестве индексной переменной не требуется. Можно использовать любой интегральный тип, если его диапазон охватывает диапазон индексов. size_t - это просто тип, который гарантированно охватывает любой возможный диапазон индексов. Я полагаю, когда вы говорите, что это имя неприемлемо, вы имеете в виду, что оно вам лично не нравится. Мне это очень нравится.   -  person Keith Thompson    schedule 15.03.2017
comment
Я бы, наверное, использовал #include <cstddef> и std::size_t, но я не утверждаю, что это принято или популярно.   -  person Keith Thompson    schedule 15.03.2017
comment
@MalcolmMcLean: Ссылка на аргумент в пользу этого, можно сказать, смелого утверждения?   -  person einpoklum    schedule 15.03.2017
comment
Это совсем не жирный шрифт, у вас есть реальные значения, целые числа и строки. Большинство целых чисел - это количество вещей в памяти или индексы в массивы или таблицы в памяти. Очевидное название для них - int.   -  person Malcolm McLean    schedule 15.03.2017
comment
@MalcolmMcLean: Может, тогда нам стоит просто избавиться от typedef. Или беззнаковых типов. Если серьезно, я просто не понимаю, что вы говорите. У меня есть всевозможные фундаментальные типы, и у меня есть определения типов, перегруженные семантикой. Пожалуйста, дайте ссылку на более серьезное обсуждение вашей точки зрения.   -  person einpoklum    schedule 15.03.2017
comment
Поскольку «size_t» приходит из разных источников, ваши читатели захотят (а иногда и должны) знать, какой «size_t» вы имеете в виду. Следовательно, мой редактор автоматически добавляет в начало (или автозаполнение?), То есть std :: size_t Никаких усилий для меня и читаемый для всех.   -  person 2785528    schedule 15.03.2017
comment
@ DOUGLASO.MOEN: Нет, size_t не приходит из разных мест. Если вы имеете в виду несколько мест в стандартной библиотеке - ну, это правда, но это одно и то же size_t. Можете ли вы показать пример size_t поступающих из разных (широко используемых) мест?   -  person einpoklum    schedule 16.03.2017
comment
@einpoklum Да, несколько мест в стандартной библиотеке.   -  person 2785528    schedule 17.03.2017
comment
@ DOUGLASO.MOEN: Но это одно и то же место, или два места - либо ::size_t, если это стандартная библиотека C, либо std::size_t, если это ее разновидность C ++.   -  person einpoklum    schedule 18.03.2017


Ответы (2)


Вы должны указать это с помощью директивы using.

using std::size_t;

Добавьте его либо в глобальную область видимости каждой единицы компиляции, либо в локальные области, если это вызовет помехи в глобальной области.

stddef.h также работает, как вы заметили, и, честно говоря, этот метод не «хуже», чем этот. Однако stddef.h является заголовком обратной совместимости, и, возможно, лучше не полагаться на него в новом коде.

Я предпочитаю директиву using, потому что она не загрязняет глобальное пространство имен там, где это вам не нужно, и не полагается на поддержку нестандартного поведения произвольным компилятором. Кроме того, это общепринятый способ переноса типа в пространство имен, когда в противном случае возможны несколько параметров, поэтому он не является уникальным для использования size_t.

Это не совсем то, на что человек может авторитетно ответить. Я был профессиональным разработчиком в течение 10 лет и работаю с C ++ с 1998 года, но я никогда не увижу статистически значимой части всего написанного кода C ++. Судя по тому, что я видел, существует множество кода, который все еще использует stddef.h, и он вряд ли сломается в ближайшее время.

Для нового кода я предпочитаю просто набирать везде префикс «std ::», применяя директивы using только тогда, когда он становится громоздким или трудным для чтения. Однако я понимаю, что это может раздражать «унаследованный» код, в котором директивы using в области видимости файла лучше. Если у вас есть время для правильного рефакторинга унаследованного кода, есть хороший аргумент, что вы должны это сделать, но, скорее всего, это будет связано не только с переменными size_t.

Я также должен упомянуть, что в C ++ FAQ (пункт 27.5) также упоминается эта проблема здесь, где у меня сложилось впечатление, что они в основном рекомендуют согласованность с другими членами вашей команды.

Я хочу отметить здесь, что НЕ является хорошей практикой применять "using namespace std" в области видимости файла, хотя это также приведет к включению size_t в глобальное пространство имен. Я приведу причину этого здесь.

Кажется, я напугал tuple_cat (извините), но я действительно думал, что его эмпирический метод был хорош, поэтому я пытаюсь внести некоторые изменения, чтобы разрешить мои опасения по поводу его ответа. Я попытался выполнить поиск в github со следующими измененными запросами, которые, по общему признанию, все еще могут иметь некоторые проблемы:

A) "size_t" AND "stddef.h" language:c++
B) "std::size_t" AND "<cstddef>" language:c++
C) "size_t" AND "<cstddef>" AND NOT "std::size_t" language:c++
D) "size_t" AND "<cstddef>" AND "using namespace std" AND NOT "std::size_t" language:c++
E) "size_t" AND "<cstddef>" AND "using std::size_t" language:c++

Получаю следующее:

  • A) 974 239 результатов (подход stddef.h)
  • B) 1 230 021 результат (подход cstddef с префиксом "std ::")
  • C) 469 721 результат (подход cstddef, без префиксов)
  • D) 32 539 результатов (подход cstddef, «использование пространства имен std», НЕ ДЕЛАЙТЕ ЭТО!)
  • E) 27 080 результатов (рекомендую метод "using std :: size_t")

Он определенно не идеален, и я приветствую критику, чтобы сделать его лучше, но похоже, что метод, который я рекомендую, как уже было сказано, не самый популярный. Судя по данным, наиболее популярным является использование префиксов «std ::» для size_t (B) с последующим включением «stddef.h» (A). К счастью, плохой подход (D) не популярен, но похоже, что многие люди могут полагаться на другие файлы / заголовки, чтобы перенести size_t в глобальное пространство имен, или просто надеяться, что он уже есть в компиляторе (C).

Следовательно, чтобы «идти в стадо», вы должны все добавить с помощью «std ::». Если вы не хотите этого делать, то "stddef.h" также очень часто используется, но я все же предпочитаю директиву using.

person Bob Miller    schedule 14.03.2017
comment
Итак, на самом деле методология отключена, потому что люди склонны использовать std:: больше в коде библиотеки, чем в приложениях, и я думаю, что это чрезмерно представлено на GitHub. Но - похоже, вы получили совсем другие числа, чем @tuple_cat. - person einpoklum; 15.03.2017
comment
Достаточно справедливо, но мне понравилось, что его метод был эмпирическим и повторяемым. Это могут быть предвзятые данные, но я просто счастлив вообще иметь данные. Я думаю, что различие между его числами и моими связано с тем, что я пытаюсь сузить свой поиск до конкретного использования size_t и различных типов использования, которые вы описали. - person Bob Miller; 15.03.2017

Итак, каков более привычный / популярный способ справиться с этим:

Вот один из способов определить это:

GitHub поиск "std::size_t" в коде C ++: 4650 049 результатов.
Поиск на GitHub "size_t" в коде C ++: 24 835 033 результатов.

Аналогично "#include <stddef.h>" дает 1 051 142 обращения, а "#include <cstddef>" дает 2 099 971. Поиск по запросу "using std::size_t;" дает только 50 057 результатов.

Выложив это здесь, делайте собственные выводы.

person emlai    schedule 14.03.2017
comment
Но как они попали size_t? - person juanchopanza; 15.03.2017
comment
Результат size_t будет приходить независимо от того, был ли :: size_t включен из stddef.h или из директивы using, поэтому этот метод не делает различий между ними. Кроме того, очевидные результаты между вашим первым результатом и вторым конфликтом: ‹cstddef› не требуется для объявления :: size_t. - person Bob Miller; 15.03.2017
comment
использование std :: size_t - не единственная директива using, которая переносит size_t в пространство имен. Другой способ сделать это - использовать пространство имен std, что, как я подозреваю, довольно распространено. Здесь не критикую: у вас есть эмпирический метод, я просто пытаюсь вытащить дыры, которые вы можете попробовать заткнуть, чтобы получить более точный ответ. - person Bob Miller; 15.03.2017
comment
@BobMiller using namespace std; - обычно плохая практика, и ее не следует использовать в глобальном масштабе. - person ; 15.03.2017
comment
@ user2176127 Однозначно согласен. Я упоминаю об этом, потому что это другой способ внести size_t в глобальное пространство имен, которое не будет обнаружено вышеупомянутым поиском. Кроме того, проблема с поиском #include заключается в том, что ‹cstddef› включает больше, чем просто size_t, поэтому по этим результатам трудно сказать, включают ли пользователи его с целью переноса size_t в пространство имен или нет. - person Bob Miller; 15.03.2017
comment
Тот факт, что люди используют size_t вместо указания std::size_t, не говорит нам, какой именно вариант они выбрали из перечисленных мною ... - person einpoklum; 15.03.2017
comment
@einpoklum Лучше всего добавить std::. С такими инструментами, как Visual Assist X или ReSharper C ++, это довольно просто сделать. Правильное регулярное выражение тоже может это сделать. Все остальное похоже на шум вокруг да около. Мои 2cts - person ; 15.03.2017
comment
@ user2176127 достаточно честно, как я уже упоминал, я считаю, что это лучший вариант для нового кода. Однако я думаю, что он приближается к полному рефакторингу кода, что приводит к вопросу о том, где прекратить рефакторинг. Я смотрел на это с точки зрения наличия кода, который нужно поддерживать, и хотел внести минимальные изменения, чтобы сделать его переносимым. - person Bob Miller; 15.03.2017
comment
конечно, использовать пространство имен std; плохо, но практика;) - person Wolf; 17.11.2017