У меня есть вопрос, касающийся областей объявления функций в C ++. Предположим, используя #include <cmath>
вводит символ функции в глобальное пространство имен. Насколько я понимаю, в принципе, он должен вводить только символы в std
пространства имен, но на практике, исходя из собственного опыта, некоторые символы появляются в глобальном пространстве имен. Этот ответ, кажется, подтверждает это: путаница с заголовком.
Теперь, что происходит, когда я объявляю функцию (с тем же прототипом, что и функция из глобального пространства имен) внутри namespace foo { }
? Предположим, например, что sqrt()
от <cmath>
заканчивается в глобальном пространстве имен, и у меня есть:
#include <cmath>
namespace foo {
template <class T>
T sqrt( T x ) {
// do something extra...
return std::sqrt( x );
}
}
// ...
void foo::bar() {
double a = 4.0;
double b = sqrt( a );
}
Шаблон разрешен к символу double sqrt( double x )
Кажется, он должен конфликтовать с глобальным пространством имен. Кажется, это работает, но это вообще плохая практика?
В более общем смысле, имеет ли функция, объявленная внутри пространства имен, приоритет перед глобальной функцией, если она используется внутри одного и того же пространства имен? Это как-то нарушает стандарт C ++?
Здесь есть два отдельных вопроса.
Во-первых, верно, что при вводе определенных заголовков символы вводятся как в глобальное пространство имен, так и в std
Пространство имен. Это производство колбасных изделий связано с наследием и корнями C ++ в C; и попытаться получить хороший шанс получить унаследованный код C, скомпилированный в C ++, с минимальными трудностями.
Во-вторых, это правда, что …
функция, объявленная внутри пространства имен, имеет приоритет над глобальной
функция, когда используется из одного и того же пространства имен?
Это правильно. И нет, это не
нарушать стандарт C ++ в любом случае?
Фактически, стандарт C ++ явно указывает, что именно так все и должно работать. При разрешении ссылки из пространства имен сначала выполняется поиск в том же пространстве имен, что и в первом порядке бизнеса. Затем родительское пространство имен, в случае вложенного пространства имен. Затем, в конце концов, глобальное пространство имен.
Затем, using namespace
усложняет ситуацию Вот почему ты не должен этого делать.
И, наконец, чтобы сделать вещи интересными, есть также зависимый от аргумента поиск это сводит все эти правила с ног на голову, ища функцию не в текущем пространстве имен, родительском пространстве имен или глобальном пространстве имен, а в том же пространстве имен, что и аргументы функций.
Никто никогда не обвинял C ++ в простоте.
Других решений пока нет …