2016-12-17 1 views
1

Je viens de tomber sur le fait que plusieurs algorithmes de l'en-tête standard algorithm ne nécessitent pas std::.Y a-t-il une raison pour laquelle find_if, for_each, count etc. ne nécessitent pas std ::?

Exemple:

#include <vector> 
#include <algorithm> 

int main() { 
    std::vector<int> m; 
    count(m.begin(), m.end(), 0); 
    count_if(m.begin(), m.end(), [](auto){return true;}); 
    for_each(m.begin(), m.end(), [](auto){}); 
    find_if(m.begin(), m.end(), [](auto){return true;}); 
} 

Live demo at coliru

Y at-il une raison particulière pour cela? Les deux g++ et clang++ acceptent le code ci-dessus.

+5

En raison de l'ADL, il est préférable de ne pas s'en remettre au cas où vous utiliseriez des conteneurs personnalisés. –

+0

https://en.wikipedia.org/wiki/Argument-dependent_name_lookup –

Répondre

6

Il y a deux choses qui se passent ici. Le premier est ADL ou Argument Dependent Name Lookup.

Les fonctions sont trouvées via ADL. En effet, certains des arguments (à savoir le type iterator de vector) se trouvent dans std, donc lorsque la résolution de surcharge recherche for_each, elle ressemble à l'ensemble habituel d'espaces de noms (racine dans ce cas), plus ceux déterminés par le namespaces de ses arguments.

L'astuce est que vector::iterator est pas garanti pour être un type dans namespace std. Donc, votre code n'est pas garanti pour fonctionner. Il peut être un type dans std, ou il pourrait être un pointeur brut, ou il pourrait être un type dans namespace __std__utility_types, ou n'importe où ailleurs.

Toutes les bibliothèques de compilation principales ont vector les itérateurs ne sont pas des pointeurs, et ils sont dans namespace std, car l'alternative est considérée comme pire. Mais le manque de garantie signifie que vous ne devriez pas compter sur lui pour le code vraiment portable.

+0

J'ai rencontré le problème que les IDE de Microsoft «trouvaient» ces fonctions exactes via ADL (leur «assistant éditeur» IntelliSense), mais sur le compilateur de temps de compilation ne parvenait pas à utiliser ADL. – Swift