Почему область действия параметра C ++ влияет на поиск функций в пространстве имен? - PullRequest
5 голосов
/ 22 марта 2011

Мне это кажется немного отсталым, но это работает:

#include <iostream>

namespace nTest
{
  struct cTest {};

  void fTest(cTest& x)
  {
    std::cout << "nTest::fTest(cTest&) called" << std::endl;
  }
}

int main(void)
{
  nTest::cTest x;
  fTest(x); //Weird! fTest is resolved since its parameter belongs to nTest.
  return 0;
}

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

Это прекрасно компилируется в GCC, но мне интересно, переносимо ли это использование? Какое официальное определение этого механизма определения объема?

Ответы [ 3 ]

13 голосов
/ 22 марта 2011

Это ADL (Argument Dependent Lookup) или Koenig Lookup (для разработчика функции).Назначение этой функции заключается в том, что во многих случаях одно и то же пространство имен будет содержать типы и функции, которые можно применять к этим типам, и все они соответствуют интерфейсу .Если бы ADL не был на месте, вам пришлось бы ввести идентификаторы в область действия с помощью объявлений using, или вы должны были бы квалифицировать вызовы.

Это становится кошмаром, поскольку язык допускает перегрузки операторов.Рассмотрим следующий пример:

namespace n {
   struct test {};
   test operator+( test, test const & ); // implemented
};
int main() {
   n::test a,b;
   n::test c = a + b;  //without ADL: c = n::operator+( a, b )
}

Хотя это может показаться неловкой ситуацией, учтите, что n может быть пространством имен std, test может быть ostream, а operator+ можетbe operator<<:

int main( int argc, char** ) {
   std::cout << "Hi there, there are " << argc << " arguments" << std::endl;
}

Без ADL вызовы operator<< должны были бы быть явными, и, кроме того, вы должны знать, какой из них реализован как свободная функция по сравнению с методом.Знаете ли вы, что std::cout << "Hi" вызывает свободную функцию, а std::cout << 5 вызывает функцию-член?Не многие это понимают, а если серьезно, то почти никому нет до этого дела.ADL скрывает это от вас.

3 голосов
/ 22 марта 2011

Это называется Koenig aka Argument зависимый поиск http://en.wikipedia.org/wiki/Argument-dependent_name_lookup

1 голос
/ 22 марта 2011

Первоначально он был разработан для поиска перегруженных операторов, таких как оператор <<, который вы используете для отправки строки в std :: cout.Если бы у нас не было ADL, вам пришлось бы писать свой код следующим образом: <code>std::operator<<(std::cout, "nTest::fTest(cTest&) called").

Не слишком приятно!

И если это работает для операторов, почему бы не работатьтак же для функций?

...