Переносит идиомы STL для удобочитаемости хорошая идея?

Я в настоящее время работаю над проектом C++, который должен иметь как можно меньше внешних зависимостей, и таким образом я в значительной степени придерживаюсь STL и Повышения. До сих пор я почти исключительно жил на Спокойной земле когда дело доходит до C++. В целом я склонен использовать C# и Python, когда я могу.

Сегодня я хотел проверить ли a std::vector содержавший определенный объект. С QT я сделал бы это как так:

QList< int > list;
list.append( 1 );
list.append( 2 );
list.append( 3 );

if ( list.contains( 2 ) )
{
    // do something
}

Хороший и читаемый. Но std::vector имеет нет contains метод, который был удивлением. Хорошо..., что было бы идиома STL для чего-то как этот быть? Ища вокруг, это, кажется, это:

std::vector< int > list;
list.push_back( 1 );
list.push_back( 2 );
list.push_back( 3 );

std::vector< int >::const_iterator result =
    std::find( list.begin(), list.end(), 2 );

if ( result != list.end() )
{
    // do something
}

Это (мне) является едва читаемым и слишком подробным. Таким образом, я писал служебную функцию, которая берет вектор и значение и возвраты bool в зависимости от того, было ли значение найдено или нет. В основном, шаблонное contains() метод; обертка для вышеупомянутого std::find звонить. Я могу затем использовать это способом, которое подобно спокойному примеру.

У меня есть несколько подобных служебных функций в памяти, которые перенесли бы другие идиомы STL ни по какой другой причине, но (воспринятому) увеличению удобочитаемости. То, что я хочу знать..., действительно ли это - плохая идея? Другие люди делают то же? Я пропускаю что-то решающее? Кодом будет OSS однажды, и я не сделал бы чего-то особенного, которое другой C++ devs нашел бы странным.

11
задан Lucas 29 July 2010 в 17:27
поделиться

6 ответов

Нет ничего плохого в написании полезных функций, которые помогут вам и сделают ваш код чище. Другие люди делают то же самое. Библиотека Boost - это самый большой набор таких вспомогательных функций и классов.

Более того, стандарт C++ явно предлагает расширять Стандартную библиотеку (17.3.1.2/1):

Библиотека может быть расширена программой на C++. Каждый пункт, в зависимости от ситуации, описывает требования, которым должны удовлетворять такие расширения. Такие расширения обычно являются одним из следующих:

  • Шаблонные аргументы
  • Производные классы
  • Контейнеры, итераторы и/или алгоритмы, которые соответствуют соглашению об интерфейсе
6
ответ дан 3 December 2019 в 05:32
поделиться

boost делает это намного аккуратнее. Я никогда не использую STL алгоритмы, основанные на итераторах. Алгоритмы, основанные на диапазоне основанные на алгоритмах диапазона, являются гораздо более аккуратной абстракцией и приводят к гораздо более чистому коду.

#include <boost/range/algorithm/find.hpp>

void foo(){
    std::vector<int> list;
    ...
    ...
    boost::find(list, 2) != list.end()
}
9
ответ дан 3 December 2019 в 05:32
поделиться

Достаточно похоже, что в моем текущем проекте у нас есть файл с именем: stlutils.h, который содержит некоторые методы, такие как contains (). Реализовано как:

template<class Container, class T>
bool contains(const Container& c, const T& value) {
   return std::find(c.begin(), c.end(), value) != c.end();
}

Есть и другие функции, но я думаю, вы поняли

1
ответ дан 3 December 2019 в 05:32
поделиться

В других ответах отмечалось, что вы можете написать служебные функции, которые будут делать это за вас, и это хорошая идея там, где вам это нужно. Но я подумал, что отмечу важный момент: STL разработан с учетом алгоритмической эффективности. Почти все операции с STL имеют стандартное требование к эффективности big-O.

Если бы вектор имел член contains () , то, безусловно, было бы O (n) для вызова, поскольку вектор является простым непрерывным списком. Поскольку это также удобно, это может побудить программистов использовать его регулярно, даже с большими наборами данных, поощряя разработку приложений с низкой алгоритмической производительностью. В случае contains () , если важно проверить, содержит ли контейнер определенный элемент, с дополнительной гарантией уникальности всех элементов, std :: set будет почти наверняка лучший выбор, с поиском эффективности O (log n) или даже O (1) для std :: unordered_set .

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

1
ответ дан 3 December 2019 в 05:32
поделиться

Я бы сказал, что это определенно хорошая идея. В C ++ STL отсутствует многое из того, что программисты Python / C # ожидают от стандартной библиотеки. Если вы можете сделать свой код более читаемым, применив подход STL из 2-3 строк и превратив его в единую функцию, продолжайте!

Вот еще один пример очень похожей проблемы: я часто хочу преобразовать int в std :: string . К моему удивлению, нет четкого способа сделать это с помощью STL. Итак, я написал функцию toStr , которая запускает 2-3 строки, необходимые для помещения int в строковый поток и возврата результирующей строки ].

Edit: Чтобы уточнить, я рекомендую поискать решения для boost , прежде чем создавать свои собственные. Мой пример был предназначен для демонстрации ограничений STL, но имеет альтернативную интерпретацию: «все, что в STL отсутствует, есть boost ».

3
ответ дан 3 December 2019 в 05:32
поделиться

Я не большой поклонник оберток, но если они вам помогут, дерзайте. Я думаю, со временем вы обнаружите, что захотите использовать свою служебную функцию с другими контейнерами, помимо std :: vector. Со временем ваша служебная функция станет настолько универсальной, что вы можете напрямую использовать std :: find.

Но вы уверены, что используете правильный контейнер? std :: set имеет метод count (), который по сути эквивалентен contains (). И это O (log (n)), а не O (n).

1
ответ дан 3 December 2019 в 05:32
поделиться
Другие вопросы по тегам:

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