Почему for_each работает без std:: prefix

Я считаю, что for_each определяется в стандартном пространстве имен, но этот код фактически компилируется и выполняется со следующими флагами компилятора. Может кто-нибудь объяснить, почему?

  //@filename myprog.cpp 
  //g++-4.5 --std=c++0x myprog.cpp

  #include<iostream>
  #include<algorithm>

  int main()
  {
    std::vector<int> v{1,2,3,4,5};
    std::cout<<"printing the number\n";
    for_each(v.begin(),v.end(),[](int num) {//no std::for_each
        std::cout<<num<<"\t";
    });
 return 0;
 }

Ответ 1

Преобразование комментария в ответ, причина, по которой это работает, - ADL (зависимый от аргумента поиск). В основном это означает, что при невозможности найти подходящее соответствие для for_each в текущем пространстве имен, у компилятора есть встроенное правило, в котором говорится, что теперь смотрите в других пространствах имен, а набор пространств имён, которые он использует для этого, - это пространства имен аргументов. После того, как он имеет набор пространств имен, он будет искать их, чтобы найти подходящий for_each.

Остается открытым вопрос, находится ли std::vector<>::iterator в std:: или нет. Очевидно, что в вашей реализации это происходит, поэтому найден соответствующий for_each в std::. Могут быть случаи, когда этот итератор не находится в std:: - чтобы быть в безопасности (как в комментарии Алана), всегда привыкайте к квалификации с помощью std::.

Кроме того, это предотвращает любые случаи, когда кто-то другой вводит в ваше пространство имен еще один for_each (для аргументов), что может нарушить ситуацию (в худшем случае - молчаливо принимает - но ломается во время выполнения).