Примеры такие как включение вывода std
типы объясняют, как ADL может использоваться для «внедрения» определенной функции / оператора, в зависимости от типа, к которому применяется fn / op.
Мне было интересно, является ли ADL полностью применимым к глобальному пространству имен, то есть, объявлен ли тип (или доступен через using
) в глобальная область имен заставляет ADL искать подходящие функции в глобальном пространстве имен?
В частности, это эквивалентно по отношению к. ADL ?:
// 1 - at global namespace scope
struct GlobalType {};
template< class Ch, class Tr>
std::basic_ostream<Ch, Tr>& operator<<(std::basic_ostream<Ch, Tr>& os, GlobalType const& x)
{
os << ...;
return os;
}
// 2 - within namespace
namespace ecaps {
struct EcapsType {};
template< class Ch, class Tr>
std::basic_ostream<Ch, Tr>& operator<<(std::basic_ostream<Ch, Tr>& os, EcapsType const& x)
{
os << ...;
return os;
}
}
// 3 - Type brought to global NS via using, function at global scope
namespace other {
struct OtherType {};
}
using other::OtherType;
template< class Ch, class Tr>
std::basic_ostream<Ch, Tr>& operator<<(std::basic_ostream<Ch, Tr>& os, OtherType const& x)
{
os << ...;
return os;
}
Wrt. глобальная область имен не нуждается в ADL: (обновить после удаленного ответа)
Один Даниэль Крюглер из комитета славы описывает проблему ADL в качестве таких:
Этот неквалифицированный вызов приводит к тому, что поиск по неквалифицированному имени
происходит, и, как следствие этого, компилятор ищет
названиеoperator<<
, начало из лексического места, где
operator<<
звонок найден «вверх» (…) начиная с текущего пространства имен и всех
пространства имен, которые включают это пространство имен (включая глобальные
пространство имен, кстати.) и — …
EMPH. мой. Обратите внимание, как описываются внешние пространства имен, чтобы считаться «… из лексического местоположения …». Он продолжает:
… и — в качестве второго маршрута — он выполняет второй этап этого
поиск компилятор ищет в так называемых связанных пространствах имен
типы аргументов, встречающиеся в этом вызове.В представленном примере первая фаза поиска заканчивается неудачей, потому что
в точке, где#include <iterator>
существует, нет
соответствующийoperator<<
для этих типов аргументов в любом пространстве имен.
Обратите внимание, что ваша декларацияoperator<<
предоставляется лексически после
точка, где зовoperator<<
происходит где-то в некоторых
заголовки библиотеки. Второй этап поиска также будет
рассмотреть места, которые
следовать фактический вызов функции, но только в пределах связанных пространств имен.
Жирный шрифт мой. Так мне показалось бы это является уместно, что ADL работает для глобального пространства имен. Конечно, я легко мог что-то неправильно понять.
Примечание: это может быть в случае со стандартом, просто не упоминая об этом так или иначе, потому что глобальный NS подобен любому другому пространству имен — опять же, может и нет, мои знания о Стандарте очень ограничены.
Полностью забудь мой первоначальный ответ, он был совершенно неверным.
Из стандарта C ++ 11, §3.4.2 по ADL (выделено мое):
Когда постфиксное выражение в вызове функции (5.2.2) является
unqualified-id, другие пространства имен не считается во время обычного
неквалифицированный поиск (3.4.1) можно искать, и в этих пространствах имен,
декларации дружественных функций в пространстве имен (11.3), не иначе
видимый может быть найден.
Короче говоря, поскольку неквалифицированный поиск всегда будет искать в глобальном пространстве имен, ADL будет никогда применить к глобальному пространству имен.