Наиболее используемый алгоритм STL, предикаты, итераторы - PullRequest
6 голосов
/ 13 марта 2009

Я не могу найти этот вопрос на stackoverflow. Но мне интересно, как люди используют STL (не модный импульс) ... просто модный STL. Трюки / советы / в основном используемые случаи, приобретенные за много-много лет ... и, возможно, ошибки ...

Давайте поделимся этим ...

Один совет за ответ ... с примером кода -

Редактировать это такой плохой вопрос, который приводит к снижению голосов?

Ответы [ 11 ]

9 голосов
/ 13 марта 2009

Мое любимое следующее, чтобы заменить что-либо растягиваемое на строку:

template <class TYPE> std::string Str( const TYPE & t ) {
    std::ostringstream os;
    os << t;
    return os.str();
}

Тогда:

string beast = Str( 666 );
7 голосов
/ 13 марта 2009

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

Токенизируйте строку ввода пробелами и введите результат в std :: vector для последующего анализа:

std::stringstream iss(input);
std::vector<std::string> * _input = new std::vector<std::string>();

std::copy(std::istream_iterator<std::string>(iss), 
          std::istream_iterator<std::string>(), 
          std::back_inserter<std::vector<std::string> >(*_input));

Другими предпочтительными вариантами являются std :: reverse и другие алгоритмы, определенные в <algorithm>.

6 голосов
/ 13 марта 2009

Мне нравится istream_iterator и ostream_iterator.

Хороший простой способ прочитать поток и сделать его похожим на любой другой контейнер:

// Copies a stream of integers on the std input
// into a vector.
int main()
{
    std::vector<int>    data;
    std::copy(std::istream_iterator<int>(std::cin),
              std::istream_iterator<>(),
              std::back_inserter(data)
             );

    // By uisng the istream_iterator<> the input just becomes another container.
}
6 голосов
/ 13 марта 2009

Использование вектора для замены указателя + новый. Это огромно.

4 голосов
/ 13 марта 2009

Я люблю вектор. Это то, чем должны быть массивы C ++ . Хотя я много работаю в режиме реального времени. Люди, которым не нужен детерминизм, могут предпочесть список.

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

Я не слишком часто использую алгоритм, так как мы все еще используем VS6 здесь (который не может обрабатывать сложные шаблоны) Это скоро пройдет.

3 голосов
/ 13 марта 2009

Самый полезный алгоритм (ИМХО) - std :: for_each

2 голосов
/ 13 марта 2009

Материал functional: bind1st, bind2nd, mem_fun, equal_to и т. Д. Очень полезен, если по какой-то причине у вас нет доступа к Boost Bind.

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

2 голосов
/ 13 марта 2009

Я не могу вспомнить, чтобы у меня был любимый или наиболее используемый алгоритм / предикат / итератор, только тот, который сделал лучшую работу для того, что я пытался выполнить в то время.

1 голос
/ 04 апреля 2009

Это несколько «зло», но оно спасло нас от многих ошибок.

(Обновление, спасибо комментарию @ Ricky65 за то, что он привел меня сюда.) C ++ 11 имеет основанный на диапазоне цикл for , который намного превосходит это, если ваш компилятор его поддерживает; мы все еще работаем с некоторыми действительно старыми компиляторами.

#define FOREACH(iter,stlContainer)  \
for ( typeof(stlContainer.begin()) iter = stlContainer.begin(), \
                                   iter##End_Cached = stlContainer.end(); \
      iter != iter##End_Cached; \
      ++iter )

(Дальнейшее обновление, спасибо разработчикам Boost.) Он основан на более сложном, но более способном макросе BOOST_FOREACH, но имеет преимущество в том, что для небольших случаев гораздо проще переходить в отладочных сборках, а не требуется небольшая куча заголовков надстроек (в некоторых кодовых базах / группах это verboten).

Использование std::for_each обычно предпочтительнее, но имеет ряд недостатков:

  • пользователи должны много знать о взаимодействиях между bind1st / bind2nd / ptr_fun / mem_fun, чтобы эффективно использовать его для нетривиального "посещения" - повышение устраняет многие из этих проблем, но не каждый имеет или знает повышение
  • пользователям может потребоваться предоставить свой отдельный функтор (обычно структуру) только для одной точки использования; указанные структуры не могут быть объявлены внутри функции, окружающей цикл, что приводит к «нелокальности» связанного кода - в некоторых случаях он не читает, а не имеет логики в соответствии с потоком остальной функции
  • это не всегда красиво встроено, в зависимости от компилятора

Макрос FOREACH, как указано выше, предоставляет несколько вещей:

  • как и std::for_each, вы не ошибетесь в граничных тестах (без повторов до конца и т. Д.)
  • будет использовать const_iterators над постоянными контейнерами

Обратите внимание, что для этого требуется несколько нестандартное расширение "typeof".

Типичное использование может быть:

list< shared_ptr< Thing > > m_memberList;
// later
FOREACH( iter, m_memberList )
{
   if ( (*iter)->getValue() < 42 ) {
      doSomethingWith( *iter );
   }
}

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

(Пожалуйста, не стесняйтесь указывать плюсы / минусы / недостатки, я обновлю ответ.)

1 голос
/ 13 марта 2009

Спроси художника "какая твоя любимая / самая используемая кисть?" :)

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