2009-03-12 11 views
6

Je ne trouve pas cette question sur stackoverflow. Mais je me demande comment les gens utilisent le STL (No Fancy Boost) ... juste une vieille mode STL. Astuces/conseils/utilisés pour la plupart des cas acquis au cours de nombreuses années ... et peut-être ... gotchasL'algorithme STL le plus utilisé, les prédicats, les itérateurs

Partageons il ...

Une astuce par réponse ... avec exemple de code -

Modifier Est-ce une mauvaise question car cela entraîne des downvotes? Utilisation de vecteur pour remplacer le pointeur + nouveau.

+1

Je trouve cette question vraiment utile. Il est cependant monté par quelques réponses inutiles ... +1 à tous ceux qui ont contribué. – AndreasT

Répondre

7

J'utilise la STL dans presque tous mes projets, pour des choses de boucles (avec des itérateurs) pour diviser l'entrée dans un programme.

Tokenise une chaîne d'entrée par des espaces et entrez le résultat dans un std :: vecteur pour l'analyse syntaxique plus tard:

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

D'autres favoris sont hors cours std :: inverse et d'autres algorithmes définis dans <algorithm>.

6

C'est énorme.

3

La plupart algorithme utile (à mon humble avis) - std :: for_each

9

Mon préféré est le suivant pour changer quoi que ce soit diffusable à une chaîne:

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

Puis:

string beast = Str(666); 
+0

boost :: lexical_cast: P –

+2

voir la question d'origine - Boost non autorisé –

+0

mais c'est à peu près exactement la source pour lexical_cast de toute façon –

1

Il y a aucun des algorithmes, prédicats ou itérateurs STL les plus utilisés. C'est comme demander quel est l'opérateur le plus utilisé en langage C++. Qu'est-ce que vous utilisez le plus souvent, operator+ ou operator-? Préférez-vous if à while? Ou peut-être à throw?

Tout est utilisé quand il doit être utilisé. PS: Je vous suggère de lire Effective STL par Scott Meyers avant de poser ces questions.

+1

J'ai ce livre –

+0

Ensuite, je suis surpris que vous avez posé cette question :) Vraiment :) – Paul

+3

Dire aux gens qu'ils sont stupides pour poser une question n'est pas utile. – catphive

1

Demandez au peintre "quel pinceau préféré/le plus utilisé?" :)

+0

Si vous laissez entendre que c'est inutile, je ne suis pas d'accord. Ils se soucient des matières premières qu'ils utilisent aussi. Les expressionnistes utilisent de gros pinceaux pour faire des traits rudes, les peintres réalistes utilisent des pinceaux très fins et peut-être des crayons etc. Des différences similaires existent dans la programmation. – Frank

+0

Je voulais dire que STL avait différents outils pour différents objectifs. Nous ne pouvons pas comparer, quel outil j'avais besoin dépendait de ma tâche actuelle. – bayda

+0

Je suis peintre ... et programmeur. Je peux vous dire que les peintres discutent souvent de leurs pinceaux, outils et techniques préférés. – Benj

2

Je ne me souviens pas d'avoir un algorithme/prédicat/itérateur favori ou le plus utilisé, juste celui qui a fait le meilleur travail pour ce que j'essayais d'accomplir à ce moment-là.

4

J'aime le vecteur. C'est ce que les tableaux C++ ont dû être. Je fais beaucoup de travail en temps réel cependant. Les gens qui n'ont pas besoin de determinisim pourraient préférer la liste.

À peu près tout le monde utilise le diable en chaîne.

Je n'utilise pas beaucoup l'algorithme, car nous utilisons encore VS6 ici (qui ne peut pas gérer les instanciations de modèles complexes). Cela passera bientôt cependant.

2

Les choses functional: bind1st, bind2nd, mem_fun, equal_to, etc. est très utile si, pour une raison, on n'a pas accès à Boost Bind.

C'est une question très subjective qui dépend beaucoup du style de codage de votre équipe, du type de projet et d'autres facteurs inconnus.

6

J'aime l'istream_iterator et l'ostream_iterator.

Une belle façon facile de lire un flux et le faire ressembler à tout autre contenant:

// 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

Oh c'est vraiment gentil! Je ne savais pas à propos de cette option merci! – petric

1

Ce qui suit est un peu « mal », mais il nous a sauvé de nombreux bugs.

(Mise à jour, merci au commentaire de @ Ricky65 pour me ramener ici.) C++ 11 a un range-based for loop qui est de loin supérieur à ceci, si votre compilateur le supporte; nous travaillons toujours avec certains vraiment vieux compilateurs, cependant.

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

(nouvelle mise à jour, le crédit aux devs Boost.) Il est vaguement basé sur le plus complexe mais plus capable BOOST_FOREACH macro, mais a l'avantage d'être beaucoup plus facile à parcourir en debug pour les petits cas, et ne nécessitant pas un petit tas d'en-têtes boost (qui dans certaines bases de code/groupes est verboten).

L'utilisation std::for_each est généralement préférable, mais a quelques inconvénients:

  • utilisateurs doivent connaître beaucoup de choses sur les interactions entre bind1st/bind2nd/ptr_fun/mem_fun à utiliser efficacement pour non-trivial "visite" - Boost corrige un grand nombre de ces problèmes, mais pas tout le monde a ou sait boost
  • les utilisateurs peuvent avoir besoin de fournir leur propre foncteur séparé (généralement une structure) pour un seul point d'utilisation; les structures ne peuvent pas être déclarées dans la fonction entourant la boucle, ce qui conduit à une "non-localité" de code apparenté - elle ne se lit pas aussi bien que d'avoir la logique en ligne avec le flux du reste de la fonction dans certains cas
  • il ne signifie pas toujours bien en ligne, selon le compilateur

La macro FOREACH comme indiqué ci-dessus fournit un certain nombre de choses:

  • comme std::for_each, vous ne recevrez pas vos tests de limites mal (pas d'itération après la fin, etc.)
  • il utilisera const_iterators sur des conteneurs constants

Notez qu'il nécessite une extension "typeof" quelque peu non standard.

Une utilisation typique pourrait être:

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

Je ne suis pas entièrement satisfait de cette macro, mais il a été très précieux ici, en particulier pour les programmeurs sans que beaucoup d'expérience dans la conception STL-aware.

(S'il vous plaît ne hésitez pas à signaler avantages/inconvénients/défauts, je vais mettre à jour la réponse.)

+0

Hah, la macro manque quelques parens de sécurité, mettra à jour dans un peu. Bien sûr, les "inconvénients" habituels de l'utilisation de la macro s'appliquent tous: eval répété, etc, etc – leander

+0

Oh. A noter que cette boucle choisit d'éviter d'évaluer à plusieurs reprises end(). Cela peut ou peut ne pas être sage en fonction de ce que vous faites dans la boucle. Bien sûr, modifier le contenu d'un conteneur pendant que vous itérez est toujours une proposition délicate ... – leander

+1

En lisant ceci en 2013, je suis heureux que range-for ait été ajouté en C++ 11. Cette macro est beurk! – Ricky65