Должны ли имена, представляющие типы шаблонов, быть одним символом? - PullRequest
5 голосов
/ 11 ноября 2010

мы определяем некоторые рекомендации по стилю кодирования C ++ на основе этих рекомендаций . Номер 8 говорит: «Имена, представляющие типы шаблонов, должны быть одной заглавной буквой». Объяснение: «Обычная практика в сообществе разработчиков C ++. Это выделяет имена шаблонов относительно всех других используемых имен».

Это действительно так часто? Я согласен, что имеет смысл иметь template<class T> class vector {...}. Но что, если у меня есть несколько шаблонных аргументов? Я не думаю, что <class A, class B> легче понять, чем <class AllocationPolicy, class ThreadingPolicy>.

Согласны ли вы с тем, что часто бывают случаи, когда данное правило не следует применять (что допускается согласно 1 ...)?

Спасибо за ваши мысли!

Ответы [ 6 ]

7 голосов
/ 11 ноября 2010

Я не совсем согласен с этим соглашением об именах. Для меня параметры шаблона, представляющие полностью универсальный тип, имеют смысл в виде простой буквы - это тип T, мне все равно, какой именно. Но если есть какие-либо требования к типу, имеет смысл создать имя, которое идентифицирует аргумент шаблона: template <typename T, typename Allocator> struct container - первый тип является универсальным, подойдет любой T, а второй - распределитель .

Он ничем не отличается от функций, в которых вы не хотите, чтобы ваши параметры назывались a, b ... по порядку или виду, а вместо этого выдают значимые имена как часть документации . Кроме того, при разработке руководства по стилю я хотел бы рассмотреть вопрос о необходимости использования локальных определений типов аргументов шаблона в случае классов шаблонов вместе со статическими утверждениями о требованиях к типам (когда это возможно). То есть, по крайней мере, пока концепции не обеспечат эту функциональность.

Я считаю STL хорошим примером библиотеки, и вы можете видеть, что генерация typedefs помогает в чтении кода (из g ++ 4.2 stl):

Классы:

// from <vector> -> <bits/stl_vector.h>
template<typename _Tp, typename _Alloc = std::allocator<_Tp> >
class vector : protected _Vector_base<_Tp, _Alloc>
{
  // Concept requirements.
  typedef typename _Alloc::value_type _Alloc_value_type; // _Alloc contains value_type internal type
  __glibcxx_class_requires(_Tp, _SGIAssignableConcept)   // _Tp is assignable
[...]
public:
   typedef _Tp value_type;                 // from here on _Tp is not mentioned
   typedef typename _Tp_alloc_type::reference reference; // check + typedef
[...]
   iterator begin() { 
   // without typedef:
   // __gnu_cxx::__normal_iterator<pointer, vector_type> begin() {
[...]
   reference operator[](size_type __n)
   // _Tp& operator[](size_type __n)
[...]

// from <memory>
template <typename _Tp>
class auto_ptr 
{
[...]
    template <typename _Tp1>
    auto_ptr(auto_ptr<_Tp1>& __a) throw() 

А функции:

template <typename _InputIterator, typename _Tp>
inline _InputIterator find( _InputIterator __first, _InputIterator __last, _Tp value ) {
  // concept requirements
  __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
  [...]

Все их имена имеют префикс _ и либо заглавную букву, либо секунду _, которые являются именами, зарезервированными для реализации, и они предпочитают _Tp над _T, но в конце вы можно видеть, что всякий раз, когда тип является универсальным , он называется _Tp, _Tp1 ..., тогда как когда к нему прикреплены некоторые конкретные требования, выбирается более разумное имя.

Между ними есть тонкая грань, как, например, в std::vector, существуют фактические требования к универсальному типу: _Tp должен быть назначаемым, но в конце дня это в основном универсальный тип. Называть его _Assignable было бы странно в некоторых контейнерах, где существует более одного требования.

4 голосов
/ 11 ноября 2010

Я думаю, это зависит от того, сколько у вас параметров.Если параметр является типом и это единственный параметр, почему он не может быть просто T?Однако я согласен с вами, что в случае нескольких параметров они должны иметь значимые имена по той же причине, по которой переменные обычно должны иметь значимые имена.

1 голос
/ 11 ноября 2010

Если это просто тип, я склонен использовать однобуквенные идентификаторы (T, U и т. Д.). Если аргумент имеет особое более ограниченное значение (предикат, распределитель и т. Д.), Я бы использовал что-то более описательное.

Тем не менее, однобуквенные идентификаторы (T) могут вызывать обратную реакцию, сталкиваясь с именами макросов (см. GCC 4.2 Странная ошибка шаблона ), что, вероятно, более вероятно при использовании более длинных идентификаторов (если они не использовать то же соглашение ALL_CAPS, что и макросы).

1 голос
/ 11 ноября 2010

Я думаю, что основная проблема с однобуквенными именами (в шаблонах и т. Д.) - это когда вы хотите выполнить поиск и замену. Если в вашем текстовом редакторе нет синтаксического анализатора C ++ (и большинство его не содержат), однобуквенные имена вызовут множество ложных совпадений, которые вы не намеревались. При использовании более длинных / описательных имен OTOH поиск и замена с большей вероятностью будут работать, как предполагалось.

1 голос
/ 11 ноября 2010

Различные стандарты кодирования будут определять разные названия. Просто выберите один и придерживайтесь его.

Мои предпочтения - иметь описательные имена, а не какое-то имя общего типа T (хотя в некоторых ситуациях это неплохо).

1 голос
/ 11 ноября 2010

Конечно, выразительные имена для типов шаблонов в порядке.Было бы еще полезнее, когда когда-нибудь в языке вводятся понятия (жаль, что они были отброшены для C ++ 0x).В то же время, имя типа параметра шаблона описывает ожидание для данного данного типа, по крайней мере, неформально (концепции дадут им формальность, перечисляя ожидаемые типы и операции, которые должен иметь тип).

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