2017-02-06 15 views
19

Как find_type Знаешь, где находится функция typemap?
Аргумент, который он получает, не из этого пространства имен, это из пространства имен std!Почему этот случай ADL работает?

#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.

+6

Параметр параметра шаблона 'T' из struct' find_type' является 'std :: unique_ptr '. 'std :: unique_ptr' рассматривает параметр шаблона' test :: Test' для ADL и, таким образом, находит функцию 'typemap' в' test' NS – SebNag

ответ

19

В C++ стандарт N4618 §3.4.2 [basic.lookup.argdep] (2,2)

Если T является типом класса (в том числе объединений), связанные с ним классы: сам класс; класс которого составляет участник, если таковой имеется; и его прямые и косвенные базовые классы. Его связанные пространства имен являются внутренними , охватывающими пространства имен связанных классов. Кроме того, если T является специализацией шаблона класса, то его ассоциированные пространства имен и классы также включают: пространства имен и классы, связанные с типами аргументов шаблона, предоставленными для параметров шаблона (исключая шаблон шаблона ); пространства имен, членами которых являются аргументы шаблона шаблона; и классы , членами которых являются любые шаблоны-члены, используемые в качестве аргументов шаблона шаблона.

Аргумент typemap является std::unique_ptr<test::Test>, поэтому пространство имен test считается для имени искать.

14

Аргумент, который он получает, не из этого пространства имен, это из пространства имен std!

Не все!

using type = decltype(typemap(std::declval<T>())); 

Это:

using type = decltype(typemap(std::declval<std::unique_ptr<test::Test>>())); 

Там же в там test::, поэтому пространство имен test ищется тоже.

 Смежные вопросы

  • Нет связанных вопросов^_^