Как профессиональные программисты C ++ реализуют общие абстракции? - PullRequest
9 голосов
/ 04 июля 2011

Я никогда не программировал на C ++ профессионально, а работал (Visual) C ++ как студент. У меня возникают трудности с отсутствием абстракций, особенно с классами контейнеров STL . Например, векторный класс не содержит простой метод remove , распространенный во многих библиотеках, например .NET Framework. Я знаю, что есть метод erase , он не делает метод remove достаточно абстрактным, чтобы свести операцию к вызову метода из одной строки. Например, если у меня есть

std::vector<std::string>

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

bool remove(vector<string> & msgs, string toRemove) {
if (msgs.size() > 0) {
    vector<string>::iterator it = msgs.end() - 1;   
    while (it >= msgs.begin()) {
        string remove = it->data();
        if (remove == toRemove) {
            //std::cout << "removing '" << it->data() << "'\n";
            msgs.erase(it);
            return true;
        }
        it--;
    }
}   
return false;

}

Что делают профессиональные программисты на С ++ в этой ситуации? Вы пишете реализацию каждый раз? Вы создаете свой собственный контейнерный класс, свою собственную библиотеку вспомогательных функций или предлагаете использовать другую библиотеку, например Boost (даже если вы программируете Windows в Visual Studio)? или что-то еще?

(если вышеуказанная операция удалить требует работы, пожалуйста, оставьте альтернативный способ сделать это, спасибо.)

Ответы [ 3 ]

9 голосов
/ 04 июля 2011

Вы бы использовали идиому «удалить и стереть»:

v.erase(std::remove(v.begin(), v.end(), mystring), v.end());

Дело в том, что vector является контейнером последовательности и не предназначен для манипулирования значением . В зависимости от ваших требований к дизайну может подойти другой стандартный контейнер библиотеки.

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

Идиоматический современный C ++ будет пытаться следовать этому шаблону всякий раз, когда это применимо: предоставлять свои данные через итераторы и использовать универсальные алгоритмы для манипулирования ими.

4 голосов
/ 04 июля 2011

Рассматривали ли вы std :: remove_if?

http://www.cplusplus.com/reference/algorithm/remove_if/

0 голосов
/ 09 июля 2011

IMO, профессионально, совершенно логично написать пользовательскую реализацию, выполняющую пользовательские задачи, особенно если стандарт не обеспечивает этого. Это намного лучше, чем писать (читай: копировать-вставлять) одни и те же вещи снова и снова. Можно также воспользоваться встроенными функциями, шаблонными функциями, макросами, чтобы разместить один и тот же материал в одном месте. Это уменьшает любые ошибки, которые могут возникнуть при повторном использовании одного и того же материала (что может пойти не так, как надо, когда вставка ) Это также позволяет исправить ошибку в одном месте.

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

Редактировать : Ваш код нуждается в улучшении:

  • bool remove (vector & msgs, cosnt string & toRemove );
  • Для итерации по коллекции достаточно цикла for. Нет необходимости проверять размер, брать последний итератор, проверять с помощью begin, получать данные и все.
  • Нет необходимости тратить a string - просто сравните его и удалите.

Для вашей проблемы, я думаю, map или set подойдут намного лучше.

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