2009-03-12 1 views
6

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

Давайте делиться ...

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

Редактировать Это такой плохой вопрос, как в результате в downvotes?

+1

Я считаю этот вопрос очень полезно. Тем не менее, он управляется некоторыми бесполезными ответами ... +1 всем, кто внес свой вклад. – AndreasT

ответ

7

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

Tokenise входной строки пробелами и ввода результата в станд :: вектор для разбора позже:

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)); 

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

6

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

3

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

9

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

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

Тогда:

string beast = Str(666); 
+0

boost :: lexical_cast: P –

+2

см. Оригинальный вопрос - повышение не допускается – 2009-03-12 22:28:34

+0

, но это в значительной степени является источником для lexical_cast в любом случае –

1

Есть не самые используемые алгоритмы STL, предикаты или итераторы. Это похоже на вопрос о том, что является наиболее используемым оператором на языке C++. Что вы используете чаще всего, operator+ или operator-? Вы предпочитаете if - while? Или, может быть, до throw?

Все используется, когда оно должно использоваться.

PS: Предлагаю вам прочитать Effective STL Скоттом Мейерсом, прежде чем задавать такие вопросы.

+1

У меня есть эта книга – 2009-03-12 22:50:55

+0

Тогда я удивлен, что вы задали этот вопрос :) Действительно :) – Paul

+3

Говорить людям, что они тупые, задавая вопрос, не полезно. – catphive

1

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

+0

Если вы подразумеваете, что это бесполезно, я не согласен. Они заботятся о сырье, которое они используют. Экспрессионисты использовали большие кисти, чтобы сделать грубые штрихи, художники-реалисты используют очень тонкие и, возможно, карандаши и т. Д. Подобные различия существуют и в программировании. – Frank

+0

Я имел в виду, что у STL были разные инструменты для разных целей. Мы не можем сравнивать, какой инструмент, который мне нужен, зависит от моей текущей задачи. – bayda

+0

Я художник ... а также программист. Могу сказать, что художники часто обсуждают свои любимые кисти, инструменты и приемы. – Benj

2

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

4

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

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

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

2

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

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

6

Мне нравится 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. 
} 
+0

О, это действительно хорошо! не знал об этом варианте спасибо! – petric

1

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

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

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

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

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

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

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

  • как std::for_each, вы не получите ваши граничные испытания неправильно (no iterating one past the end и т. д.)
  • он будет использовать const_iterators над постоянными контейнерами

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

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

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

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

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

+0

Hah, макрос не хватает некоторых парсер безопасности, обновит это немного. Разумеется, применяются обычные «минусы» использования макросов: повторная оценка и т. Д. И т. Д. – leander

+0

Ох. Стоит отметить, что этот цикл выбирает, чтобы избежать неоднократной оценки end(). Это может быть или не быть разумным в зависимости от того, что вы делаете в цикле. Конечно, изменение содержимого контейнера при повторном запуске всегда является сложным предложением ... – leander

+1

Чтение этого в 2013 году заставляет меня радоваться, что диапазон добавлен в C++ 11. Этот макрос! – Ricky65