Подтвердить что ты не робот

Почему это дело 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.

4b9b3361

Ответ 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 также выполняется.