Каково соглашение о присвоении имен, когда typdef сложный STL отображается?

Вы можете передать в функцию несколько параметров.

def printBill(bill)

становится:

def printBill(bill,hours):

, и вы называете его с помощью:

printBill(bill,hours)

Вам также нужно будет передать его getSavings таким же образом.

12
задан SCFrench 2 May 2011 в 13:16
поделиться

9 ответов

Я предпочитаю следующее соглашение:

typedef std::map< Foo, Bar > FooToBarMap

Я намеренно избегаю определения типов итераторов, я предпочитаю явно ссылаться на них as:

FooToBarMap::const_iterator

Поскольку итераторы уже являются de facto стандартным typename. Я считаю, что FooToBarMapConstIter на самом деле менее понятен для чтения при скимминге кода.

16
ответ дан 2 December 2019 в 18:22
поделиться

В отношении этих имен не существует общепринятого правила. Обычно я использую имя класса «value» с суффиксом Map. В вашем примере это будет SomeOtherClassMap . Я использую это соглашение, потому что обычно более интересно, что ваша карта содержит объекты «значения» типа SomeOtherClass , а затем вы просматриваете их с помощью «ключей» из SomeClass .

2
ответ дан 2 December 2019 в 18:22
поделиться

Мне наиболее интересна вторая часть вопроса. Я предпочитаю помещать typedef в классы, которые их используют, когда для них есть логическое место, даже если они используются в других классах. Но это вызывает некоторые проблемы с прямыми объявлениями (которые мы часто используем для повышения скорости компиляции).

Например, в одном недавнем проекте у нас был класс под названием Io со встроенным typedef под названием Point , который создавал очень читаемый код - Io: : Пункт очень четкий и читаемый. Но всякий раз, когда мы хотели использовать тип, нам приходилось включать объявление класса Io , даже если все, что нам нужно, было объявление Io :: Point , поскольку нет никакого способа (что я знаю) для прямого объявления типа, который находится в классе, объявленном вперед.

В этом случае мы сделали это обоими способами. Мы создали глобальный тип IoPoint , а затем к нему typedef d Io :: Point (чтобы не пришлось изменять уже написанный код ). Не самый красивый ответ, но он сделал свою работу.

Что касается других частей:

Мы не используем никаких специальных соглашений для имен. Для карт мы часто используем * DescriptiveSomething *** Map ** (поскольку маловероятно, что мы когда-либо перейдем с карты на какой-либо другой тип контейнера), но если DescriptiveSomething достаточно информативен и не конфликтует с существующим именем, мы часто будем его использовать.

Обычно мы не утруждаем себя созданием определений типов для итераторов, поскольку легко (и очень удобно) просто использовать Type :: iterator или Type :: const_iterator . Тем не менее, мы выполняем иногда typedef, если имя типа настолько длинное, что Type :: const_iterator делает код слишком «коренастым». (Не знаю лучшего способа сказать это, но вы, вероятно, знаете, что я имею в виду.)

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

2
ответ дан 2 December 2019 в 18:22
поделиться

Нет, просто имейте в виду общие правила именования идентификаторов (нет _ для начала с так далее). Кроме того, если в вашей организации есть руководство по кодированию, лучше всего придерживаться его.

Часто, когда вы определяете свой собственный шаблонный класс, он становится беспорядочным без typedefs - поэтому я бы создал их там как удобные ярлыки. Однако, если это действительно куча классов, я бы предпочел иметь их на уровне пространства имен .

0
ответ дан 2 December 2019 в 18:22
поделиться

Мы используем следующее на моем рабочем месте:

typedef std::map WhateverMap;
typedef WhateverMap::iterator WhateverIter;
typedef WhateverMap::const_iterator WhateverCIter;

Что касается местоположения, то оно меняется. Если он специфичен для класса, он может быть в структуре Impl или в защищенной или закрытой области объявления класса. Если он более общий (используется в файлах, используется в API), мы помещаем его в отдельный заголовок стиля «FooTypes.h».

Обратите внимание, что, поскольку для нас часто бывает необходимо изменить базовый тип, мы можем использовать « Wh whatCollection "вместо" WheverVec "или" WheverList ". Нередки случаи, когда «WheverList» фактически определяется по типу для вектора или слайса, в зависимости от требуемой площади и характеристик производительности.

0
ответ дан 2 December 2019 в 18:22
поделиться

Я не знаю, существуют ли какие-либо формальные правила по этому вопросу, но я обычно добавляю определения типов в месте, наиболее подходящие для использования в проекте.

  • Если typedef используется только в одном классе, тогда добавьте typedef в определение класса
  • Если typedef используется несколькими несвязанными классами, добавьте его в файл заголовка на уровне области пространства имен

Что касается фактического имени типа typedef'd. Я называю это тем, что имеет смысл для typedef. Я не даю именам typedef никаких специальных соглашений, таких как префикс _t или что-то в этом роде. Например,

typedef stl::map<stl::string,Student> NameToStudentMap;
0
ответ дан 2 December 2019 в 18:22
поделиться

Обычно я определяю связанное имя с typedef, указывающее тип объекта.

Пример:

typedef std::vector<ClassCompStudent*> StudentCollection;

typedef std::map<std::string /*id*/, ClassCompStudent* /*pStudent*/>  IDToStudentMap;

Кроме того, я определяю их как общедоступные в заголовке класса, в котором был создан объект. Это дает мне возможность изменять тип контейнера без нарушения клиентского кода.

class Test
{
public:
    typedef std::vector<ClassCompStudent*> StudentCollection;

    /* Users of Test need not know whether I use vector or list for 
        storing students. They get student collection and use it*/
    bool getStudents(StudentCollection& studentList) const;

    void print()
    {
        //do printing
    }
private:

    StudentCollection m_StudentList;
};

bool function(const Test& testObj)
{
    //If StudentCollection gets changed to list, this code need not be changed.
    StudentCollection aCollection;
    testObj.getStudents(aCollection);
    std::for_each(aCollection.begin(), aCollection.end(), std::mem_fun(&Test::print));
}
0
ответ дан 2 December 2019 в 18:22
поделиться

Интересный вопрос:
Я посмотрел в boost и вижу, что у них нет каких-либо глобальных правил, но наиболее часто используемые соглашения

typedef std::map< key, value > some_domain_specific_name_map;

или

typedef std::map< key, value > some_domain_specific_name_map_type;

также являются хорошей практикой для создания typedef для value_type или итераторов, обычно они имеют то же имя, что и map, но с окончанием _value_type, _iterator.

0
ответ дан 2 December 2019 в 18:22
поделиться

Использование слова «Карта» или «Вектор» в виде бесполезной записи. Это слова, связанные с реализацией, а не с бизнес-моделью.

Вам не нужно показывать, что этот тип является вектором или картой. Вы можете использовать список. Как

typedef std::vector<std::string> List;
typedef std::set<std::string> List;

Это оба списки строк. И это правда.

typedef std::map<std::string, Object> List;
or  
typedef std::map<std::string, Object> NamedList;

Суть в том, что я не использую венгерскую нотацию.

0
ответ дан 2 December 2019 в 18:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: