Работает ли ADL для глобального пространства имен?

Примеры такие как включение вывода 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 подобен любому другому пространству имен — опять же, может и нет, мои знания о Стандарте очень ограничены.

3

Решение

Полностью забудь мой первоначальный ответ, он был совершенно неверным.

Из стандарта C ++ 11, §3.4.2 по ADL (выделено мое):

Когда постфиксное выражение в вызове функции (5.2.2) является
unqualified-id, другие пространства имен не считается во время обычного
неквалифицированный поиск
(3.4.1) можно искать, и в этих пространствах имен,
декларации дружественных функций в пространстве имен (11.3), не иначе
видимый может быть найден.

Короче говоря, поскольку неквалифицированный поиск всегда будет искать в глобальном пространстве имен, ADL будет никогда применить к глобальному пространству имен.

1

Другие решения


По вопросам рекламы [email protected]