Почему это дело ADL работает?
Как find_type
знать, где находится функция typemap
?
Аргумент, который он получает, не из этого пространства имен, а из пространства имен std
!
#include <type_traits>
#include <memory>
namespace lib {
template<typename T>
struct find_type {
using type = decltype(typemap(std::declval<T>()));
};
}
namespace test {
struct Test {};
auto typemap(std::unique_ptr<Test>) -> int;
}
static_assert(std::is_same<int, lib::find_type<std::unique_ptr<test::Test>>::type>::value, "");
Как этот код может работать? Что такое правило, разрешающее это?
Я тестировал его с помощью GCC 6.3 и clang 3.9.1.
Ответы
Ответ 1
В стандарте С++ N4618 §3.4.2 [basic.lookup.argdep] (2.2)
Если T - тип класса (включая союзы), его ассоциированные классы: сам класс; класс которого он член, если таковой имеется; и его прямые и косвенные базовые классы. Его связанные пространства имен являются самыми внутренними охватывающих пространства имен связанных классов. Кроме того, если T является специализацией шаблона класса, его связанные пространства имен и классы также включают в себя: пространства имен и классы, связанные с типы аргументов шаблона, предоставленные для параметров типа шаблона (исключая шаблон шаблона параметры); пространства имен, членами которых являются аргументы шаблона шаблона; и классы из которых любые члены-шаблоны, используемые в качестве аргументов шаблона шаблона, являются членами.
Аргумент typemap
равен std::unique_ptr<test::Test>
, поэтому пространство имен test
рассматривается для поиска имени.
Ответ 2
Аргумент, который он получает, не принадлежит этому пространству имен, он из пространства имен std!
Не все!
using type = decltype(typemap(std::declval<T>()));
Это:
using type = decltype(typemap(std::declval<std::unique_ptr<test::Test>>()));
Там a test::
, поэтому пространство имен test
также выполняется.